From a86951c7905af77e1627f7af3fa82b2a461f5a69 Mon Sep 17 00:00:00 2001 From: Abdul Kinadiyil Date: Tue, 22 May 2018 12:53:02 -0500 Subject: [PATCH 01/26] Enhanced the tool to define JSON entities local to the corresponding REST endpoints, send empty root element for GET operation to the SOAP backend service using an optional setting --- src/main/java/com/apigee/oas/OASUtils.java | 10 +++++ .../com/apigee/proxywriter/GenerateProxy.java | 40 ++++++++++++++----- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/apigee/oas/OASUtils.java b/src/main/java/com/apigee/oas/OASUtils.java index f86fc20..0b22930 100644 --- a/src/main/java/com/apigee/oas/OASUtils.java +++ b/src/main/java/com/apigee/oas/OASUtils.java @@ -104,6 +104,16 @@ public static void addObject(JsonObject parent, String parentName, String object properties.add(objectName, object); } + public static void addObject(JsonObject parent, String parentName, String objectName,boolean isChildComplexType, String qNameLocal) { + JsonObject properties = parent.getAsJsonObject("properties"); + JsonObject object = new JsonObject(); + if(isChildComplexType) + { + object.addProperty("$ref", "#/definitions/"+qNameLocal); + } + properties.add(objectName, object); + } + public static JsonObject createComplexType(String name, String min, String max) { JsonObject complexType = new JsonObject(); JsonObject properties = new JsonObject(); diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index dba21c4..ee8de58 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -147,6 +147,7 @@ public class GenerateProxy { private boolean ALLPOST; // set this to true if oauth should be added to the proxy private boolean OAUTH; + // set this to true if apikey should be added to the proxy private boolean APIKEY; // enable this flag if api key based quota is enabled @@ -159,6 +160,8 @@ public class GenerateProxy { private boolean RPCSTYLE; // enable this flag if user sets desc private boolean DESCSET; + // set this to true if allowEmptyNodes should be added to the proxy + private boolean ALLOW_EMPTY_NODES; // fail safe measure when schemas are heavily nested or have 100s of // elements private boolean TOO_MANY; @@ -244,6 +247,7 @@ public GenerateProxy() { ALLPOST = false; PASSTHRU = false; OAUTH = false; + ALLOW_EMPTY_NODES = false; APIKEY = false; QUOTAAPIKEY = false; QUOTAOAUTH = false; @@ -320,6 +324,10 @@ public void setPort(String prt) { public void setOAuth(boolean oauth) { OAUTH = oauth; } + + public void setAllowEmptyNodes(boolean allowEmptyNodes) { + ALLOW_EMPTY_NODES = allowEmptyNodes; + } public String getTargetEndpoint() { return targetEndpoint; @@ -637,15 +645,17 @@ private void writeSOAP2APIProxyEndpoint(String proxyDescription) throws Exceptio step2.appendChild(name2); request.appendChild(step2); - if (apiMap.getJsonBody() != null) { - step3 = proxyDefault.createElement("Step"); - name3 = proxyDefault.createElement("Name"); - name3.setTextContent("remove-empty-nodes"); - Node condition3 = proxyDefault.createElement("Condition"); - condition3.setTextContent("(verb == \"GET\")"); - step3.appendChild(name3); - step3.appendChild(condition3); - request.appendChild(step3); + if(!ALLOW_EMPTY_NODES) { + if (apiMap.getJsonBody() != null) { + step3 = proxyDefault.createElement("Step"); + name3 = proxyDefault.createElement("Name"); + name3.setTextContent("remove-empty-nodes"); + Node condition3 = proxyDefault.createElement("Condition"); + condition3.setTextContent("(verb == \"GET\")"); + step3.appendChild(name3); + step3.appendChild(condition3); + request.appendChild(step3); + } } LOGGER.fine("Assign Message: " + buildSOAPPolicy); @@ -1520,8 +1530,8 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js ComplexType ct = (ComplexType) typeDefinition; JsonObject rootElement = OASUtils.createComplexType(e.getName(), e.getMinOccurs(), e.getMaxOccurs()); - OASUtils.addObject(parent, parentName, e.getName()); - definitions.add(e.getName(), rootElement); + OASUtils.addObject(parent, parentName, e.getName(), true,e.getType().getLocalPart()); + definitions.add(e.getType().getLocalPart(), rootElement); parseSchema(ct.getModel(), schemas, e.getName(), rootElement); } } @@ -2886,6 +2896,7 @@ public static void usage() { System.out.println("-basepath=specify base path"); System.out.println("-cors= default is false"); System.out.println("-debug= default is false"); + System.out.println("-allowEmptyNodes= default is false; works only if it is set to true"); System.out.println(""); System.out.println(""); System.out.println("Examples:"); @@ -3002,7 +3013,10 @@ public static void main(String[] args) throws Exception { opt.getSet().addOption("oas", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); // set this flag to enable debug opt.getSet().addOption("debug", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); + // add verify allowEmptyNodes policy + opt.getSet().addOption("allowEmptyNodes", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); + opt.check(); if (opt.getSet().isSet("wsdl")) { @@ -3080,6 +3094,10 @@ public static void main(String[] args) throws Exception { } } + if (opt.getSet().isSet("allowEmptyNodes")) { + genProxy.setAllowEmptyNodes(new Boolean(opt.getSet().getOption("allowEmptyNodes").getResultValue(0))); + } + if (opt.getSet().isSet("apikey")) { genProxy.setAPIKey(new Boolean(opt.getSet().getOption("apikey").getResultValue(0))); if (opt.getSet().isSet("quota")) { From 15238c080e562c38b7985bc37f6746cff7bc5a8d Mon Sep 17 00:00:00 2001 From: Abdul Kinadiyil Date: Mon, 28 May 2018 06:36:11 -0500 Subject: [PATCH 02/26] Implemented following changes > 1. Handle SOAP headers for http POST method endpoints > 2. Mapping of XML Schema extension to JSON entities > Item 1 requires additional flag to be set -allowSoapHeaders=true --- src/main/java/com/apigee/oas/OASUtils.java | 8 + .../com/apigee/proxywriter/GenerateProxy.java | 345 +++++++++++++++--- .../templates/soap2api/ExtractPolicy-xslt.xml | 7 + 3 files changed, 312 insertions(+), 48 deletions(-) create mode 100644 src/main/resources/templates/soap2api/ExtractPolicy-xslt.xml diff --git a/src/main/java/com/apigee/oas/OASUtils.java b/src/main/java/com/apigee/oas/OASUtils.java index 0b22930..e6a6b4e 100644 --- a/src/main/java/com/apigee/oas/OASUtils.java +++ b/src/main/java/com/apigee/oas/OASUtils.java @@ -144,6 +144,14 @@ public static JsonObject createComplexType(String name, String min, String max) } return complexType; } + public static JsonObject createExtension(String baseName) { + JsonObject extension = new JsonObject(); + JsonObject properties = new JsonObject(); + extension.addProperty("type", "object"); + extension.add("properties", properties); + + return extension; + } public static JsonObject createSimpleType(String type, String min, String max) { JsonObject simpleType = new JsonObject(); diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index ee8de58..f431270 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -112,6 +112,10 @@ public class GenerateProxy { private static final String SOAP2API_PROXY_TEMPLATE = "/templates/soap2api/proxyDefault.xml"; private static final String SOAP2API_TARGET_TEMPLATE = "/templates/soap2api/targetDefault.xml"; private static final String SOAP2API_EXTRACT_TEMPLATE = "/templates/soap2api/ExtractPolicy.xml"; + + //added to created Extract Variable to fetch XPATH which have SOAP Body for POST call + private static final String SOAP2API_EXTRACT_XPATH_TEMPLATE = "/templates/soap2api/ExtractPolicy-xslt.xml"; + private static final String SOAP2API_ASSIGN_TEMPLATE = "/templates/soap2api/AssignMessagePolicy.xml"; private static final String SOAP2API_XSLT11POLICY_TEMPLATE = "/templates/soap2api/add-namespace11.xml"; private static final String SOAP2API_XSLT11_TEMPLATE = "/templates/soap2api/add-namespace11.xslt"; @@ -162,6 +166,10 @@ public class GenerateProxy { private boolean DESCSET; // set this to true if allowEmptyNodes should be added to the proxy private boolean ALLOW_EMPTY_NODES; + + // set this to true if allowSoapHeaders should be added to the proxy + private boolean ALLOW_SOAP_HEADERS; + // fail safe measure when schemas are heavily nested or have 100s of // elements private boolean TOO_MANY; @@ -216,6 +224,11 @@ public class GenerateProxy { private String oasContent; // store openapi query params private ArrayList queryParams; + + private static String soapHeader = ""; + private String xpathNameSpace; + private String xpathNameSpaceURI; + // initialize the logger static { @@ -248,6 +261,7 @@ public GenerateProxy() { PASSTHRU = false; OAUTH = false; ALLOW_EMPTY_NODES = false; + ALLOW_SOAP_HEADERS = false; APIKEY = false; QUOTAAPIKEY = false; QUOTAOAUTH = false; @@ -329,6 +343,10 @@ public void setAllowEmptyNodes(boolean allowEmptyNodes) { ALLOW_EMPTY_NODES = allowEmptyNodes; } + public void setAllowSoapHeaders(boolean allowSoapHeaders) { + ALLOW_SOAP_HEADERS = allowSoapHeaders; + } + public String getTargetEndpoint() { return targetEndpoint; } @@ -400,6 +418,8 @@ private void writeSOAP2APIProxyEndpoint(String proxyDescription) throws Exceptio .readXML(buildFolder + File.separator + "apiproxy" + File.separator + proxyName + ".xml"); Document extractTemplate = xmlUtils.readXML(SOAP2API_EXTRACT_TEMPLATE); + + Document extractXpathTemplate = xmlUtils.readXML(SOAP2API_EXTRACT_XPATH_TEMPLATE); Document assignTemplate = xmlUtils.readXML(SOAP2API_ASSIGN_TEMPLATE); @@ -594,6 +614,7 @@ private void writeSOAP2APIProxyEndpoint(String proxyDescription) throws Exceptio APIMap apiMap = entry.getValue(); String buildSOAPPolicy = operationName + "-build-soap"; String extractPolicyName = operationName + "-extract-query-param"; + String extractPolicyForXPATH = operationName + "-extract-from-xpath"; String jsonToXML = operationName + "-json-to-xml"; // String jsPolicyName = operationName + "-root-wrapper"; String jsonToXMLCondition = "(request.header.Content-Type == \"application/json\")"; @@ -662,21 +683,6 @@ private void writeSOAP2APIProxyEndpoint(String proxyDescription) throws Exceptio LOGGER.fine("Extract Variable: " + extractPolicyName); } else { - // add root wrapper policy - /* - * name3.setTextContent(jsPolicyName); step3.appendChild(name3); - * step3.appendChild(condition2.cloneNode(true)); - * request.appendChild(step3); - */ - - // add the root wrapper only once - /* - * if (!once) { Node resourceRootWrapper = - * apiTemplateDocument.createElement("Resource"); - * resourceRootWrapper.setTextContent("jsc://root-wrapper.js"); - * resources.appendChild(resourceRootWrapper); once = true; } - */ - name1.setTextContent(jsonToXML); step1.appendChild(name1); step1.appendChild(condition2); @@ -688,19 +694,39 @@ private void writeSOAP2APIProxyEndpoint(String proxyDescription) throws Exceptio step2.appendChild(name2); request.appendChild(step2); + if (apiMap.getOthernamespaces()) { - name4.setTextContent(operationName + "-add-other-namespaces"); + name3.setTextContent(operationName + "-add-other-namespaces"); + step3.appendChild(name3); + request.appendChild(step3); + } + + if(ALLOW_SOAP_HEADERS) { + step4 = proxyDefault.createElement("Step"); + name4 = proxyDefault.createElement("Name"); + name4.setTextContent(operationName+"-extract-from-xpath"); step4.appendChild(name4); request.appendChild(step4); } - + // for soap 1.1 add soap action if (soapVersion.equalsIgnoreCase(SOAP_11)) { - step5 = proxyDefault.createElement("Step"); - name5 = proxyDefault.createElement("Name"); - name5.setTextContent(addSoapAction); - step5.appendChild(name5); - request.appendChild(step5); + + if(!ALLOW_SOAP_HEADERS) { + step5 = proxyDefault.createElement("Step"); + name5 = proxyDefault.createElement("Name"); + name5.setTextContent(addSoapAction); + step5.appendChild(name5); + request.appendChild(step5); + }else { + step5 = proxyDefault.createElement("Step"); + name5 = proxyDefault.createElement("Name"); + name5.setTextContent(buildSOAPPolicy); + step5.appendChild(name5); + request.appendChild(step5); + + } + } } @@ -731,33 +757,24 @@ private void writeSOAP2APIProxyEndpoint(String proxyDescription) throws Exceptio apiMap.getSoapAction()); } else { - /* - * Node policy2 = apiTemplateDocument.createElement("Policy"); - * policy2.setTextContent(jsPolicyName); - * policies.appendChild(policy2); - */ - - // writeRootWrapper(jsPolicyTemplate, operationName, - // apiMap.getRootElement()); - Node policy1 = apiTemplateDocument.createElement("Policy"); policy1.setTextContent(jsonToXML); policies.appendChild(policy1); writeJsonToXMLPolicy(jsonXMLTemplate, operationName, apiMap.getRootElement()); - Node policy3 = apiTemplateDocument.createElement("Policy"); - policy3.setTextContent(operationName + "add-namespace"); - policies.appendChild(policy3); + Node policy2 = apiTemplateDocument.createElement("Policy"); + policy2.setTextContent(operationName + "add-namespace"); + policies.appendChild(policy2); Node resourceAddNamespaces = apiTemplateDocument.createElement("Resource"); resourceAddNamespaces.setTextContent("xsl://" + operationName + "add-namespace.xslt"); resources.appendChild(resourceAddNamespaces); if (apiMap.getOthernamespaces()) { - Node policy4 = apiTemplateDocument.createElement("Policy"); - policy4.setTextContent(operationName + "add-other-namespaces"); + Node policy3 = apiTemplateDocument.createElement("Policy"); + policy3.setTextContent(operationName + "add-other-namespaces"); - policies.appendChild(policy4); + policies.appendChild(policy3); Node resourceAddOtherNamespaces = apiTemplateDocument.createElement("Resource"); resourceAddOtherNamespaces.setTextContent("xsl://" + operationName + "add-other-namespaces.xslt"); @@ -767,13 +784,31 @@ private void writeSOAP2APIProxyEndpoint(String proxyDescription) throws Exceptio } else { writeAddNamespace(addNamespaceTemplate, operationName, false); } + + if(ALLOW_SOAP_HEADERS) { + Node policy4 = apiTemplateDocument.createElement("Policy"); + policy4.setTextContent(operationName+"Extract-from-xpath"); + policies.appendChild(policy4); + extractDetailsFromXpath(extractXpathTemplate, operationName, extractPolicyForXPATH); + } + + // for soap 1.1 add soap action if (soapVersion.equalsIgnoreCase(SOAP_11)) { // Add policy to proxy.xml - Node policy5 = apiTemplateDocument.createElement("Policy"); - policy5.setTextContent(addSoapAction); - policies.appendChild(policy5); - writeAddSoapAction(addSoapActionTemplate, operationName, apiMap.getSoapAction()); + + if(!ALLOW_SOAP_HEADERS) { + Node policy5 = apiTemplateDocument.createElement("Policy"); + policy5.setTextContent(addSoapAction); + policies.appendChild(policy5); + writeAddSoapAction(addSoapActionTemplate, operationName, apiMap.getSoapAction()); + }else { + Node policy5 = apiTemplateDocument.createElement("Policy"); + policy5.setTextContent(buildSOAPPolicy); + policies.appendChild(policy5); + writeSOAP2APIAMPoliciesForPOST(assignTemplate, operationName, buildSOAPPolicy, + apiMap.getSoapAction(),soapHeader); + } } } } @@ -830,6 +865,146 @@ private void writeSOAP2APIProxyEndpoint(String proxyDescription) throws Exceptio }.getClass().getEnclosingMethod().getName()); } + /* + * method used to frame ExtractVariable policy which is used to retrieve SOAP BODY from XSLT using XPATH. + * + */ + private void extractDetailsFromXpath(Document extractXpathTemplate, String operationName, String extractPolicyForXPATH) throws Exception { + // TODO Auto-generated method stub + + LOGGER.entering(GenerateProxy.class.getName(), new Object() { + }.getClass().getEnclosingMethod().getName()); + XMLUtils xmlUtils = new XMLUtils(); + + Element namespaces; + Element namespace1; + Element namespace2; + Element Variable; + Document extractPolicyXML = xmlUtils.cloneDocument(extractXpathTemplate); + + + Node rootElement = extractPolicyXML.getFirstChild(); + NamedNodeMap attr = rootElement.getAttributes(); + Node nodeAttr = attr.getNamedItem("name"); + nodeAttr.setNodeValue(extractPolicyForXPATH); + + Node displayName = extractPolicyXML.getElementsByTagName("DisplayName").item(0); + displayName.setTextContent(operationName + " Extract Xpath Details"); + + Node xmlPayload = extractPolicyXML.getElementsByTagName("XMLPayload").item(0); + namespaces = extractPolicyXML.createElement("Namespaces"); + namespace1 = extractPolicyXML.createElement("Namespace"); + namespace1.setAttribute("prefix", "soapenv"); + namespace1.setTextContent("http://schemas.xmlsoap.org/soap/envelope/"); + + namespace2 = extractPolicyXML.createElement("Namespace"); + namespace2.setAttribute("prefix", xpathNameSpace); + namespace2.setTextContent(xpathNameSpaceURI); + namespaces.appendChild(namespace1); + namespaces.appendChild(namespace2); + + Element Xpath = extractPolicyXML.createElement("XPath"); + Xpath.setTextContent("/soapenv:Envelope/soapenv:Body/"+xpathNameSpace+":"+operationName); + Variable = extractPolicyXML.createElement("Variable"); + Variable.setAttribute("name", "soapBodyFromXSL"); + Variable.setAttribute("type", "nodeset"); + Variable.appendChild(Xpath); + namespaces.appendChild(Variable); + xmlPayload.appendChild(namespaces); + xmlPayload.appendChild(Variable); + + + xmlUtils.writeXML(extractPolicyXML, buildFolder + File.separator + "apiproxy" + File.separator + "policies" + + File.separator + extractPolicyForXPATH + ".xml"); + LOGGER.exiting(GenerateProxy.class.getName(), new Object() { + }.getClass().getEnclosingMethod().getName()); + + } + + /* + * method used to create AssignMessage policy with SOAP Headers from WSDL under payload tag. + * + */ + private void writeSOAP2APIAMPoliciesForPOST(Document assignTemplate, String operationName, String policyName, + String soapAction,String soapHeader) throws Exception { + + LOGGER.entering(GenerateProxy.class.getName(), new Object() { + }.getClass().getEnclosingMethod().getName()); + XMLUtils xmlUtils = new XMLUtils(); + + Document assignPolicyXML = xmlUtils.cloneDocument(assignTemplate); + + Node rootElement = assignPolicyXML.getFirstChild(); + NamedNodeMap attr = rootElement.getAttributes(); + Node nodeAttr = attr.getNamedItem("name"); + nodeAttr.setNodeValue(policyName); + + Node displayName = assignPolicyXML.getElementsByTagName("DisplayName").item(0); + displayName.setTextContent(operationName + " Build SOAP"); + + Node payload = assignPolicyXML.getElementsByTagName("Payload").item(0); + NamedNodeMap payloadNodeMap = payload.getAttributes(); + Node payloadAttr = payloadNodeMap.getNamedItem("contentType"); + + if (soapVersion.equalsIgnoreCase(SOAP_11)) { + payloadAttr.setNodeValue(StringEscapeUtils.escapeXml10(SOAP11_PAYLOAD_TYPE)); + + assignPolicyXML.getElementsByTagName("Header").item(1) + .setTextContent(StringEscapeUtils.escapeXml10(SOAP11_CONTENT_TYPE)); + + if (soapAction != null) { + Node header = assignPolicyXML.getElementsByTagName("Header").item(0); + header.setTextContent(soapAction); + } else { + final Node add = assignPolicyXML.getElementsByTagName("Add").item(0); + add.getParentNode().removeChild(add); + } + } else { + payloadAttr.setNodeValue(StringEscapeUtils.escapeXml10(SOAP12_PAYLOAD_TYPE)); + + assignPolicyXML.getElementsByTagName("Header").item(1) + .setTextContent(StringEscapeUtils.escapeXml10(SOAP12_CONTENT_TYPE)); + } + + // APIMap apiMap = messageTemplates.get(operationName); + Document operationPayload = null; + + String soapHeaderXMLFirst = ""; + + String soapHeaderXMLEnd = "{soapBodyFromXSL}"; + + soapHeader = soapHeaderXMLFirst+soapHeader+soapHeaderXMLEnd; + // edgeui-654 (check for getBytes().length + if (xmlUtils.isValidXML(soapHeader) && soapHeader.getBytes().length < 4096) { + // JIRA-EDGEUI-672 + operationPayload = xmlUtils.getXMLFromString(replaceReservedVariables(soapHeader)); + } else { + LOGGER.warning("Operation " + operationName + " soap template could not be generated"); + if (soapVersion.equalsIgnoreCase(SOAP_11)) { + operationPayload = xmlUtils.getXMLFromString(emptySoap11); + } else { + operationPayload = xmlUtils.getXMLFromString(emptySoap12); + } + } + + Node importedNode = assignPolicyXML.importNode(operationPayload.getDocumentElement(), true); + payload.appendChild(importedNode); + + Node value = assignPolicyXML.getElementsByTagName("Value").item(0); + value.setTextContent(targetEndpoint); + + LOGGER.fine("Generated resource xml: " + buildFolder + File.separator + "apiproxy" + File.separator + "policies" + + File.separator + policyName + ".xml"); + + xmlUtils.writeXML(assignPolicyXML, buildFolder + File.separator + "apiproxy" + File.separator + "policies" + + File.separator + policyName + ".xml"); + + LOGGER.exiting(GenerateProxy.class.getName(), new Object() { + }.getClass().getEnclosingMethod().getName()); + } + + + private void writeOAS(Document returnOpenApiTemplate) throws Exception { LOGGER.entering(GenerateProxy.class.getName(), new Object() { }.getClass().getEnclosingMethod().getName()); @@ -1530,6 +1705,8 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js ComplexType ct = (ComplexType) typeDefinition; JsonObject rootElement = OASUtils.createComplexType(e.getName(), e.getMinOccurs(), e.getMaxOccurs()); + xpathNameSpace = e.getType().getPrefix(); + xpathNameSpaceURI = e.getNamespaceUri(); OASUtils.addObject(parent, parentName, e.getName(), true,e.getType().getLocalPart()); definitions.add(e.getType().getLocalPart(), rootElement); parseSchema(ct.getModel(), schemas, e.getName(), rootElement); @@ -1649,7 +1826,11 @@ else if (sc instanceof Sequence) { } else if (sc instanceof ComplexContent) { ComplexContent complexContent = (ComplexContent) sc; Derivation derivation = complexContent.getDerivation(); - + if(derivation != null && derivation.getClass().getSimpleName().equals("Extension")) + { + parseExtension(sc,schemas,rootElementName,rootElement); + return; + } if (derivation != null) { TypeDefinition typeDefinition = getTypeFromSchema(derivation.getBase(), schemas); if (typeDefinition instanceof ComplexType) { @@ -1680,6 +1861,37 @@ else if (sc instanceof Sequence) { } } } + private void parseExtension(SchemaComponent sc,List schemas, String rootElementName,JsonObject rootElement) + { + //TypeDefinition typeDefinition = getTypeFromSchema(((ComplexContent) sc).getDerivation().getBase(), schemas); + JsonObject extension = OASUtils.createExtension(((ComplexContent) sc).getDerivation().getBase().getLocalPart()); + String name= ((com.predic8.schema.ComplexType)sc.getParent()).getName(); + Derivation extElement = ((ComplexContent) sc).getDerivation(); + LOGGER.info("derivation in parseExtension"+extElement.getModel().getAsString()); + TypeDefinition typeDefinition = getTypeFromSchema(((ComplexContent) sc).getDerivation().getBase(), schemas); + Sequence seqBase = (Sequence) ((ComplexType) typeDefinition).getModel(); + parseSequence(seqBase,schemas,name,extension); + Sequence seq = (Sequence) extElement.getModel(); + parseSequence(seq,schemas,name,extension); + definitions.add(name, extension); + LOGGER.info("rootElementName=="+rootElementName+"JsonObject rootElement object=="+rootElement); + } + private void parseSequence(Sequence seq, List schemas, String rootElementName,JsonObject rootElement) + { + for (com.predic8.schema.Element e : seq.getElements()) { + if (e.getType() != null) { + if (isPrimitive(e.getType().getLocalPart())) { + JsonObject properties = rootElement.getAsJsonObject("properties"); + properties.add(e.getName(), OASUtils.createSimpleType(e.getType().getLocalPart(), + e.getMinOccurs(), e.getMaxOccurs())); + } else { + parseElement(e, schemas, rootElement, rootElementName); + } + } else { + parseElement(e, schemas, rootElement, rootElementName); + } + } + } private void parseSchema(SchemaComponent sc, List schemas, String rootElement, String rootNamespace, String rootPrefix) { @@ -2537,7 +2749,19 @@ private void parseWSDL() throws Exception { } TypeDefinition typeDefinition = null; - + KeyValue kv = null; + if(ALLOW_SOAP_HEADERS) { + creator.setCreator(new RequestTemplateCreator()); + creator.createRequest(port.getName(), op.getName(), binding.getName()); + + kv = xmlUtils + .replacePlaceHolders(writer.toString()); + + soapHeader = retrieveSoapHeaderFromEnvolope(kv.getKey()); + + writer.getBuffer().setLength(0); + } + if (requestElement.getEmbeddedType() != null) { typeDefinition = requestElement.getEmbeddedType(); } else { @@ -2565,11 +2789,21 @@ private void parseWSDL() throws Exception { xmlUtils.generateOtherNamespacesXSLT(SOAP2API_XSL, op.getName(), rs.getTransform(soapVersion), namespace); ruleList.clear(); - apiMap = new APIMap("", "", resourcePath, verb, requestElement.getName(), - true); + if(!ALLOW_SOAP_HEADERS) { + apiMap = new APIMap("", "", resourcePath, verb, requestElement.getName(), + true); + }else { + apiMap = new APIMap(kv.getValue(), kv.getKey(), resourcePath, verb, + requestElement.getName(), false); + } } else { - apiMap = new APIMap("", "", resourcePath, verb, requestElement.getName(), - false); + if(!ALLOW_SOAP_HEADERS) { + apiMap = new APIMap("", "", resourcePath, verb, requestElement.getName(), + false); + }else { + apiMap = new APIMap(kv.getValue(), kv.getKey(), resourcePath, verb, + requestElement.getName(), false); + } } } } @@ -2618,6 +2852,14 @@ private void parseWSDL() throws Exception { }.getClass().getEnclosingMethod().getName()); } + private String retrieveSoapHeaderFromEnvolope(String soapString) { + // TODO Auto-generated method stub + + String soapHeaderStr = soapString.substring(soapString.indexOf(""),soapString.indexOf("")+"".length()+1); + soapHeaderStr = soapHeaderStr.replaceAll("s11", "soapenv"); + return soapHeaderStr; + } + private String generateOAS() throws Exception { LOGGER.entering(GenerateProxy.class.getName(), new Object() { @@ -2897,6 +3139,7 @@ public static void usage() { System.out.println("-cors= default is false"); System.out.println("-debug= default is false"); System.out.println("-allowEmptyNodes= default is false; works only if it is set to true"); + System.out.println("-allowSoapHeaders= default is false; works only if it is set to true"); System.out.println(""); System.out.println(""); System.out.println("Examples:"); @@ -3015,6 +3258,8 @@ public static void main(String[] args) throws Exception { opt.getSet().addOption("debug", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); // add verify allowEmptyNodes policy opt.getSet().addOption("allowEmptyNodes", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); + // add verify allowEmptyNodes policy + opt.getSet().addOption("allowSoapHeaders", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); opt.check(); @@ -3097,7 +3342,11 @@ public static void main(String[] args) throws Exception { if (opt.getSet().isSet("allowEmptyNodes")) { genProxy.setAllowEmptyNodes(new Boolean(opt.getSet().getOption("allowEmptyNodes").getResultValue(0))); } - + + if (opt.getSet().isSet("allowSoapHeaders")) { + genProxy.setAllowSoapHeaders(new Boolean(opt.getSet().getOption("allowSoapHeaders").getResultValue(0))); + } + if (opt.getSet().isSet("apikey")) { genProxy.setAPIKey(new Boolean(opt.getSet().getOption("apikey").getResultValue(0))); if (opt.getSet().isSet("quota")) { diff --git a/src/main/resources/templates/soap2api/ExtractPolicy-xslt.xml b/src/main/resources/templates/soap2api/ExtractPolicy-xslt.xml new file mode 100644 index 0000000..d46ee55 --- /dev/null +++ b/src/main/resources/templates/soap2api/ExtractPolicy-xslt.xml @@ -0,0 +1,7 @@ + + + Extract 1 + request + true + + \ No newline at end of file From 83dd355ae48255215e817414976d8aa62acc9fb9 Mon Sep 17 00:00:00 2001 From: Abdul Kinadiyil Date: Tue, 29 May 2018 11:35:57 -0500 Subject: [PATCH 03/26] Implemented changes for mapping XML schema restriction element to JSON entity attribute in OAS --- src/main/java/com/apigee/oas/OASUtils.java | 6 +++++ .../com/apigee/proxywriter/GenerateProxy.java | 25 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/main/java/com/apigee/oas/OASUtils.java b/src/main/java/com/apigee/oas/OASUtils.java index e6a6b4e..d819fa5 100644 --- a/src/main/java/com/apigee/oas/OASUtils.java +++ b/src/main/java/com/apigee/oas/OASUtils.java @@ -152,6 +152,12 @@ public static JsonObject createExtension(String baseName) { return extension; } + public static JsonObject createRestriction(String type, String min, String max) { + JsonObject restriction = createSimpleType(type,min,max); + JsonArray enumArray = new JsonArray(); + restriction.add("enum", enumArray); + return restriction; + } public static JsonObject createSimpleType(String type, String min, String max) { JsonObject simpleType = new JsonObject(); diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index f431270..e53cc70 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -1693,6 +1693,31 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js LOGGER.warning("unhandle conditions getRef() = null"); } } else { + LOGGER.info("element name=="+e.getName() + ", element type=="+e.getType() + ",embedded type"+e.getEmbeddedType()); + if(e.getType() != null) + { + TypeDefinition typeDefinition = getTypeFromSchema(e.getType(), schemas); + if(typeDefinition instanceof com.predic8.schema.SimpleType) + { + com.predic8.schema.SimpleType simpleType = (com.predic8.schema.SimpleType )typeDefinition; + com.predic8.schema.restriction.BaseRestriction baseRestriction = simpleType.getRestriction(); + if(baseRestriction != null && baseRestriction.getBase().getLocalPart().equals("string")) + { + JsonObject restriction = OASUtils.createRestriction(baseRestriction.getBase().getLocalPart(), e.getMinOccurs(), e.getMaxOccurs()); + JsonArray enumArray = (JsonArray)restriction.get("enum"); + + for (com.predic8.schema.restriction.facet.EnumerationFacet en : baseRestriction.getEnumerationFacets()) { + LOGGER.info("Restriction value =="+en.getValue()); + enumArray.add(new JsonPrimitive(en.getValue())); + } + JsonObject properties = parent.getAsJsonObject("properties"); + properties.add(e.getName(), restriction); + LOGGER.info("Parent=="+parent); + return; + } + + } + } if (e.getEmbeddedType() instanceof ComplexType) { ComplexType ct = (ComplexType) e.getEmbeddedType(); JsonObject rootElement = OASUtils.createComplexType(e.getName(), e.getMinOccurs(), e.getMaxOccurs()); From 50c9001c7cccc0e8ed5d64d5f5e26dfb8d1bd647 Mon Sep 17 00:00:00 2001 From: Abdul Kinadiyil Date: Wed, 30 May 2018 14:56:18 -0500 Subject: [PATCH 04/26] Fixed OAS JSON entity mapping for array of elements with XML schema restriction --- src/main/java/com/apigee/oas/OASUtils.java | 11 ++++++++++- .../java/com/apigee/proxywriter/GenerateProxy.java | 7 ++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/apigee/oas/OASUtils.java b/src/main/java/com/apigee/oas/OASUtils.java index d819fa5..a9a90b6 100644 --- a/src/main/java/com/apigee/oas/OASUtils.java +++ b/src/main/java/com/apigee/oas/OASUtils.java @@ -155,7 +155,16 @@ public static JsonObject createExtension(String baseName) { public static JsonObject createRestriction(String type, String min, String max) { JsonObject restriction = createSimpleType(type,min,max); JsonArray enumArray = new JsonArray(); - restriction.add("enum", enumArray); + if(restriction.get("items") != null) + { + JsonObject items = (JsonObject)restriction.get("items"); + items.add("enum", enumArray); + } + else + { + restriction.add("enum", enumArray); + } + return restriction; } diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index e53cc70..75077fb 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -1699,12 +1699,17 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js TypeDefinition typeDefinition = getTypeFromSchema(e.getType(), schemas); if(typeDefinition instanceof com.predic8.schema.SimpleType) { + LOGGER.info("Parent1*****"+parent); com.predic8.schema.SimpleType simpleType = (com.predic8.schema.SimpleType )typeDefinition; com.predic8.schema.restriction.BaseRestriction baseRestriction = simpleType.getRestriction(); if(baseRestriction != null && baseRestriction.getBase().getLocalPart().equals("string")) { JsonObject restriction = OASUtils.createRestriction(baseRestriction.getBase().getLocalPart(), e.getMinOccurs(), e.getMaxOccurs()); - JsonArray enumArray = (JsonArray)restriction.get("enum"); + JsonArray enumArray = null; + if(restriction.get("items")==null) + enumArray = (JsonArray)restriction.get("enum"); + else + enumArray = (JsonArray)((JsonObject)restriction.get("items")).get("enum"); for (com.predic8.schema.restriction.facet.EnumerationFacet en : baseRestriction.getEnumerationFacets()) { LOGGER.info("Restriction value =="+en.getValue()); From 62ea817393398942616c277f81fb4939e2c2e58b Mon Sep 17 00:00:00 2001 From: Abdul Kinadiyil Date: Fri, 1 Jun 2018 07:32:05 -0500 Subject: [PATCH 05/26] Addressed Following issues > 1. Incorrect parameters for the OAS REST endpoint when corresponding WSDL operation has just the root element as input. > 2. When XML data is converted to JSON, optional elements had incorrect default value as NULL string. Corresponding > JSON attributes will be set to null. --- .../com/apigee/proxywriter/GenerateProxy.java | 70 ++----------------- .../templates/soap2api/xml-to-json.xml | 3 +- 2 files changed, 5 insertions(+), 68 deletions(-) diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index 75077fb..a4e3f1b 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -1693,36 +1693,6 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js LOGGER.warning("unhandle conditions getRef() = null"); } } else { - LOGGER.info("element name=="+e.getName() + ", element type=="+e.getType() + ",embedded type"+e.getEmbeddedType()); - if(e.getType() != null) - { - TypeDefinition typeDefinition = getTypeFromSchema(e.getType(), schemas); - if(typeDefinition instanceof com.predic8.schema.SimpleType) - { - LOGGER.info("Parent1*****"+parent); - com.predic8.schema.SimpleType simpleType = (com.predic8.schema.SimpleType )typeDefinition; - com.predic8.schema.restriction.BaseRestriction baseRestriction = simpleType.getRestriction(); - if(baseRestriction != null && baseRestriction.getBase().getLocalPart().equals("string")) - { - JsonObject restriction = OASUtils.createRestriction(baseRestriction.getBase().getLocalPart(), e.getMinOccurs(), e.getMaxOccurs()); - JsonArray enumArray = null; - if(restriction.get("items")==null) - enumArray = (JsonArray)restriction.get("enum"); - else - enumArray = (JsonArray)((JsonObject)restriction.get("items")).get("enum"); - - for (com.predic8.schema.restriction.facet.EnumerationFacet en : baseRestriction.getEnumerationFacets()) { - LOGGER.info("Restriction value =="+en.getValue()); - enumArray.add(new JsonPrimitive(en.getValue())); - } - JsonObject properties = parent.getAsJsonObject("properties"); - properties.add(e.getName(), restriction); - LOGGER.info("Parent=="+parent); - return; - } - - } - } if (e.getEmbeddedType() instanceof ComplexType) { ComplexType ct = (ComplexType) e.getEmbeddedType(); JsonObject rootElement = OASUtils.createComplexType(e.getName(), e.getMinOccurs(), e.getMaxOccurs()); @@ -1856,11 +1826,7 @@ else if (sc instanceof Sequence) { } else if (sc instanceof ComplexContent) { ComplexContent complexContent = (ComplexContent) sc; Derivation derivation = complexContent.getDerivation(); - if(derivation != null && derivation.getClass().getSimpleName().equals("Extension")) - { - parseExtension(sc,schemas,rootElementName,rootElement); - return; - } + if (derivation != null) { TypeDefinition typeDefinition = getTypeFromSchema(derivation.getBase(), schemas); if (typeDefinition instanceof ComplexType) { @@ -1891,37 +1857,6 @@ else if (sc instanceof Sequence) { } } } - private void parseExtension(SchemaComponent sc,List schemas, String rootElementName,JsonObject rootElement) - { - //TypeDefinition typeDefinition = getTypeFromSchema(((ComplexContent) sc).getDerivation().getBase(), schemas); - JsonObject extension = OASUtils.createExtension(((ComplexContent) sc).getDerivation().getBase().getLocalPart()); - String name= ((com.predic8.schema.ComplexType)sc.getParent()).getName(); - Derivation extElement = ((ComplexContent) sc).getDerivation(); - LOGGER.info("derivation in parseExtension"+extElement.getModel().getAsString()); - TypeDefinition typeDefinition = getTypeFromSchema(((ComplexContent) sc).getDerivation().getBase(), schemas); - Sequence seqBase = (Sequence) ((ComplexType) typeDefinition).getModel(); - parseSequence(seqBase,schemas,name,extension); - Sequence seq = (Sequence) extElement.getModel(); - parseSequence(seq,schemas,name,extension); - definitions.add(name, extension); - LOGGER.info("rootElementName=="+rootElementName+"JsonObject rootElement object=="+rootElement); - } - private void parseSequence(Sequence seq, List schemas, String rootElementName,JsonObject rootElement) - { - for (com.predic8.schema.Element e : seq.getElements()) { - if (e.getType() != null) { - if (isPrimitive(e.getType().getLocalPart())) { - JsonObject properties = rootElement.getAsJsonObject("properties"); - properties.add(e.getName(), OASUtils.createSimpleType(e.getType().getLocalPart(), - e.getMinOccurs(), e.getMaxOccurs())); - } else { - parseElement(e, schemas, rootElement, rootElementName); - } - } else { - parseElement(e, schemas, rootElement, rootElementName); - } - } - } private void parseSchema(SchemaComponent sc, List schemas, String rootElement, String rootNamespace, String rootPrefix) { @@ -2923,6 +2858,9 @@ private String generateOAS() throws Exception { continue; } + //added this line to resolve conflicts in adding parameters to resources. + queryParams.clear(); + operation = new JsonObject(); operationDetails = new JsonObject(); diff --git a/src/main/resources/templates/soap2api/xml-to-json.xml b/src/main/resources/templates/soap2api/xml-to-json.xml index 107c0a8..dba90a4 100755 --- a/src/main/resources/templates/soap2api/xml-to-json.xml +++ b/src/main/resources/templates/soap2api/xml-to-json.xml @@ -5,10 +5,9 @@ true true true - NULL TEXT @ response response - \ No newline at end of file + From 63b267869e19bc2045af8127dfa05899a10e2a65 Mon Sep 17 00:00:00 2001 From: Abdul Kinadiyil Date: Fri, 1 Jun 2018 08:22:09 -0500 Subject: [PATCH 06/26] Addressed Following issues > 1. Incorrect parameters for the OAS REST endpoint when corresponding WSDL operation has just the root element as input. --- .../com/apigee/proxywriter/GenerateProxy.java | 68 ++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index a4e3f1b..1e06c25 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -1693,6 +1693,36 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js LOGGER.warning("unhandle conditions getRef() = null"); } } else { + LOGGER.info("element name=="+e.getName() + ", element type=="+e.getType() + ",embedded type"+e.getEmbeddedType()); + if(e.getType() != null) + { + TypeDefinition typeDefinition = getTypeFromSchema(e.getType(), schemas); + if(typeDefinition instanceof com.predic8.schema.SimpleType) + { + LOGGER.info("Parent1*****"+parent); + com.predic8.schema.SimpleType simpleType = (com.predic8.schema.SimpleType )typeDefinition; + com.predic8.schema.restriction.BaseRestriction baseRestriction = simpleType.getRestriction(); + if(baseRestriction != null && baseRestriction.getBase().getLocalPart().equals("string")) + { + JsonObject restriction = OASUtils.createRestriction(baseRestriction.getBase().getLocalPart(), e.getMinOccurs(), e.getMaxOccurs()); + JsonArray enumArray = null; + if(restriction.get("items")==null) + enumArray = (JsonArray)restriction.get("enum"); + else + enumArray = (JsonArray)((JsonObject)restriction.get("items")).get("enum"); + + for (com.predic8.schema.restriction.facet.EnumerationFacet en : baseRestriction.getEnumerationFacets()) { + LOGGER.info("Restriction value =="+en.getValue()); + enumArray.add(new JsonPrimitive(en.getValue())); + } + JsonObject properties = parent.getAsJsonObject("properties"); + properties.add(e.getName(), restriction); + LOGGER.info("Parent=="+parent); + return; + } + + } + } if (e.getEmbeddedType() instanceof ComplexType) { ComplexType ct = (ComplexType) e.getEmbeddedType(); JsonObject rootElement = OASUtils.createComplexType(e.getName(), e.getMinOccurs(), e.getMaxOccurs()); @@ -1826,7 +1856,11 @@ else if (sc instanceof Sequence) { } else if (sc instanceof ComplexContent) { ComplexContent complexContent = (ComplexContent) sc; Derivation derivation = complexContent.getDerivation(); - + if(derivation != null && derivation.getClass().getSimpleName().equals("Extension")) + { + parseExtension(sc,schemas,rootElementName,rootElement); + return; + } if (derivation != null) { TypeDefinition typeDefinition = getTypeFromSchema(derivation.getBase(), schemas); if (typeDefinition instanceof ComplexType) { @@ -1857,6 +1891,37 @@ else if (sc instanceof Sequence) { } } } + private void parseExtension(SchemaComponent sc,List schemas, String rootElementName,JsonObject rootElement) + { + //TypeDefinition typeDefinition = getTypeFromSchema(((ComplexContent) sc).getDerivation().getBase(), schemas); + JsonObject extension = OASUtils.createExtension(((ComplexContent) sc).getDerivation().getBase().getLocalPart()); + String name= ((com.predic8.schema.ComplexType)sc.getParent()).getName(); + Derivation extElement = ((ComplexContent) sc).getDerivation(); + LOGGER.info("derivation in parseExtension"+extElement.getModel().getAsString()); + TypeDefinition typeDefinition = getTypeFromSchema(((ComplexContent) sc).getDerivation().getBase(), schemas); + Sequence seqBase = (Sequence) ((ComplexType) typeDefinition).getModel(); + parseSequence(seqBase,schemas,name,extension); + Sequence seq = (Sequence) extElement.getModel(); + parseSequence(seq,schemas,name,extension); + definitions.add(name, extension); + LOGGER.info("rootElementName=="+rootElementName+"JsonObject rootElement object=="+rootElement); + } + private void parseSequence(Sequence seq, List schemas, String rootElementName,JsonObject rootElement) + { + for (com.predic8.schema.Element e : seq.getElements()) { + if (e.getType() != null) { + if (isPrimitive(e.getType().getLocalPart())) { + JsonObject properties = rootElement.getAsJsonObject("properties"); + properties.add(e.getName(), OASUtils.createSimpleType(e.getType().getLocalPart(), + e.getMinOccurs(), e.getMaxOccurs())); + } else { + parseElement(e, schemas, rootElement, rootElementName); + } + } else { + parseElement(e, schemas, rootElement, rootElementName); + } + } + } private void parseSchema(SchemaComponent sc, List schemas, String rootElement, String rootNamespace, String rootPrefix) { @@ -2857,7 +2922,6 @@ private String generateOAS() throws Exception { if (selectedOperationList.size() > 0 && !selectedOperationList.containsKey(op.getName())) { continue; } - //added this line to resolve conflicts in adding parameters to resources. queryParams.clear(); From 0e29f6847f12affd3d164680f64895298111123b Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Mon, 4 Jun 2018 15:44:42 -0400 Subject: [PATCH 07/26] Update GenerateProxy.java modified to enable root element for response definitions in OAS , flag is showRespRootElement = true --- .../com/apigee/proxywriter/GenerateProxy.java | 48 +++++++++++++++++-- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index 1e06c25..f5225db 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -169,6 +169,8 @@ public class GenerateProxy { // set this to true if allowSoapHeaders should be added to the proxy private boolean ALLOW_SOAP_HEADERS; + + private boolean SHOW_RESP_ROOT_ELEMENT; // fail safe measure when schemas are heavily nested or have 100s of // elements @@ -229,6 +231,10 @@ public class GenerateProxy { private String xpathNameSpace; private String xpathNameSpaceURI; + private boolean outputOASRootElement = false; + + + // initialize the logger static { @@ -262,6 +268,7 @@ public GenerateProxy() { OAUTH = false; ALLOW_EMPTY_NODES = false; ALLOW_SOAP_HEADERS = false; + SHOW_RESP_ROOT_ELEMENT = false; APIKEY = false; QUOTAAPIKEY = false; QUOTAOAUTH = false; @@ -347,6 +354,10 @@ public void setAllowSoapHeaders(boolean allowSoapHeaders) { ALLOW_SOAP_HEADERS = allowSoapHeaders; } + public void setShowRespRootElement(boolean showRespRootElement) { + SHOW_RESP_ROOT_ELEMENT = showRespRootElement; + } + public String getTargetEndpoint() { return targetEndpoint; } @@ -1692,7 +1703,7 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js // TODO: handle this LOGGER.warning("unhandle conditions getRef() = null"); } - } else { + }else { LOGGER.info("element name=="+e.getName() + ", element type=="+e.getType() + ",embedded type"+e.getEmbeddedType()); if(e.getType() != null) { @@ -1737,7 +1748,14 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js e.getMaxOccurs()); xpathNameSpace = e.getType().getPrefix(); xpathNameSpaceURI = e.getNamespaceUri(); - OASUtils.addObject(parent, parentName, e.getName(), true,e.getType().getLocalPart()); + + if(outputOASRootElement) { + OASUtils.addObjectOutputRes(parent, parentName, e.getName(), true,e.getType().getLocalPart()); + outputOASRootElement = false; + }else { + OASUtils.addObject(parent, parentName, e.getName(), true,e.getType().getLocalPart()); + } + definitions.add(e.getType().getLocalPart(), rootElement); parseSchema(ct.getModel(), schemas, e.getName(), rootElement); } @@ -1891,6 +1909,7 @@ else if (sc instanceof Sequence) { } } } + private void parseExtension(SchemaComponent sc,List schemas, String rootElementName,JsonObject rootElement) { //TypeDefinition typeDefinition = getTypeFromSchema(((ComplexContent) sc).getDerivation().getBase(), schemas); @@ -1922,7 +1941,7 @@ private void parseSequence(Sequence seq, List schemas, String rootElemen } } } - + private void parseSchema(SchemaComponent sc, List schemas, String rootElement, String rootNamespace, String rootPrefix) { @@ -2538,6 +2557,14 @@ private void getOASDefinitions(Definitions wsdl, com.predic8.schema.Element e) { if (typeDefinition instanceof ComplexType) { ComplexType ct = (ComplexType) typeDefinition; JsonObject rootElement = OASUtils.createComplexType(e.getName(), e.getMinOccurs(), e.getMaxOccurs()); + JsonObject tempRootElement = rootElement; + JsonObject rootInnerElement; + if(outputOASRootElement) { + rootInnerElement = OASUtils.createComplexTypeOP(e.getName(), rootElement); + tempRootElement.add("properties", rootInnerElement); + rootElement = tempRootElement; + } + definitions.add(e.getName(), rootElement); parseSchema(ct.getModel(), wsdl.getSchemas(), e.getName(), rootElement); } @@ -2924,7 +2951,7 @@ private String generateOAS() throws Exception { } //added this line to resolve conflicts in adding parameters to resources. queryParams.clear(); - + operation = new JsonObject(); operationDetails = new JsonObject(); @@ -2967,9 +2994,13 @@ private String generateOAS() throws Exception { if (op.getOutput().getMessage().getParts().size() > 0) { com.predic8.schema.Element eOutput = op.getOutput().getMessage().getParts().get(0).getElement(); if (eOutput != null) { + if(SHOW_RESP_ROOT_ELEMENT) { + outputOASRootElement = true; + } getOASDefinitions(wsdl, eOutput); operationDetails.add("responses", OASUtils.getResponse(eOutput.getName())); } + outputOASRootElement = false; } } } catch (Exception e) { @@ -3172,6 +3203,7 @@ public static void usage() { System.out.println("-debug= default is false"); System.out.println("-allowEmptyNodes= default is false; works only if it is set to true"); System.out.println("-allowSoapHeaders= default is false; works only if it is set to true"); + System.out.println("-showRespRootElement= default is false; works only if it is set to true"); System.out.println(""); System.out.println(""); System.out.println("Examples:"); @@ -3290,8 +3322,10 @@ public static void main(String[] args) throws Exception { opt.getSet().addOption("debug", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); // add verify allowEmptyNodes policy opt.getSet().addOption("allowEmptyNodes", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); - // add verify allowEmptyNodes policy + // add allowSoapHeaders functionality opt.getSet().addOption("allowSoapHeaders", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); + // add showRespRootElement to show response root elements in OAS + opt.getSet().addOption("showRespRootElement", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); opt.check(); @@ -3378,6 +3412,10 @@ public static void main(String[] args) throws Exception { if (opt.getSet().isSet("allowSoapHeaders")) { genProxy.setAllowSoapHeaders(new Boolean(opt.getSet().getOption("allowSoapHeaders").getResultValue(0))); } + + if (opt.getSet().isSet("showRespRootElement")) { + genProxy.setShowRespRootElement(new Boolean(opt.getSet().getOption("showRespRootElement").getResultValue(0))); + } if (opt.getSet().isSet("apikey")) { genProxy.setAPIKey(new Boolean(opt.getSet().getOption("apikey").getResultValue(0))); From 7da5ef2c08bc92ccb3ec7e25055fb0692602bd20 Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Mon, 4 Jun 2018 15:45:40 -0400 Subject: [PATCH 08/26] Update OASUtils.java modified to enable root element for response definitions in OAS --- src/main/java/com/apigee/oas/OASUtils.java | 34 +++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/apigee/oas/OASUtils.java b/src/main/java/com/apigee/oas/OASUtils.java index a9a90b6..3b4c262 100644 --- a/src/main/java/com/apigee/oas/OASUtils.java +++ b/src/main/java/com/apigee/oas/OASUtils.java @@ -112,8 +112,24 @@ public static void addObject(JsonObject parent, String parentName, String object object.addProperty("$ref", "#/definitions/"+qNameLocal); } properties.add(objectName, object); + + } + + /* + * inorder to retrieve inner properties attribute to assign output elements + * + */ + public static void addObjectOutputRes(JsonObject parent, String parentName, String objectName,boolean isChildComplexType, String qNameLocal) { + JsonObject properties = parent.getAsJsonObject("properties").getAsJsonObject(parentName).getAsJsonObject("properties"); + JsonObject object = new JsonObject(); + if(isChildComplexType) + { + object.addProperty("$ref", "#/definitions/"+qNameLocal); + } + properties.add(objectName, object); } + public static JsonObject createComplexType(String name, String min, String max) { JsonObject complexType = new JsonObject(); JsonObject properties = new JsonObject(); @@ -132,7 +148,7 @@ public static JsonObject createComplexType(String name, String min, String max) Integer minimum = Integer.parseInt(min); complexType.add("properties", properties); - + if (maximum == -1 || maximum > 1) { complexType.addProperty("type", "array"); //in json schemas, if the elements are unbounded, don't set maxItems @@ -144,6 +160,7 @@ public static JsonObject createComplexType(String name, String min, String max) } return complexType; } + public static JsonObject createExtension(String baseName) { JsonObject extension = new JsonObject(); JsonObject properties = new JsonObject(); @@ -168,6 +185,21 @@ public static JsonObject createRestriction(String type, String min, String max) return restriction; } + /* + * Method used to create inner properties for each response attribute under #definitions of OAS + * + */ + public static JsonObject createComplexTypeOP(String name, JsonObject jsonObj) { + JsonObject properties = jsonObj.getAsJsonObject("properties"); + JsonObject innerProp = new JsonObject(); + JsonObject jsoonOuterProp = new JsonObject(); + jsoonOuterProp.add("properties", innerProp); + properties.add(name, jsoonOuterProp); + + return properties; + } + + public static JsonObject createSimpleType(String type, String min, String max) { JsonObject simpleType = new JsonObject(); String oasDataType = ""; From b0bf2030889fcbed00a38804a923cae2acd97675 Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Tue, 5 Jun 2018 19:40:50 -0400 Subject: [PATCH 09/26] Update GenerateProxy.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit modified to resolve issue with nillable attribute when values are coming empty. ex:“@nil":true,"TEXT":null will be replaced with null. --- .../com/apigee/proxywriter/GenerateProxy.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index f5225db..a9ec37b 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -1368,6 +1368,11 @@ private void writeStdPolicies() throws Exception { + File.separator; String xslResourcePath = buildFolder + File.separator + "apiproxy" + File.separator + "resources" + File.separator + "xsl" + File.separator; + + String jsResourcePath = buildFolder + File.separator + "apiproxy" + + File.separator + "resources" + File.separator + "jsc" + + File.separator; + /* * String jsResourcePath = buildFolder + File.separator + "apiproxy" * + File.separator + "resources" + File.separator + "jsc" + @@ -1435,6 +1440,16 @@ private void writeStdPolicies() throws Exception { Files.copy(getClass().getResourceAsStream(sourcePath + "remove-namespaces.xslt"), Paths.get(xslResourcePath + "remove-namespaces.xslt"), java.nio.file.StandardCopyOption.REPLACE_EXISTING); + //Added java script policy to remove nillable attributes in response + Files.copy(getClass().getResourceAsStream(sourcePath + "remove-nillable.xml"), + Paths.get(targetPath + "remove-nillable.xml"), + java.nio.file.StandardCopyOption.REPLACE_EXISTING); + + Files.copy(getClass().getResourceAsStream(sourcePath + "remove-nillable.js"), + Paths.get(jsResourcePath + "remove-nillable.js"), + java.nio.file.StandardCopyOption.REPLACE_EXISTING); + + /* * Files.copy(getClass().getResourceAsStream(sourcePath + * "root-wrapper.js"), Paths.get(jsResourcePath + From cf97085a0d7b25b259dfd86143079c777db3d3fd Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Tue, 5 Jun 2018 19:43:21 -0400 Subject: [PATCH 10/26] Add files via upload added files to address when wsdl have nillable="true" --- .../templates/soap2api/remove-nillable.js | 40 +++++++++++++++++++ .../templates/soap2api/remove-nillable.xml | 6 +++ 2 files changed, 46 insertions(+) create mode 100644 src/main/resources/templates/soap2api/remove-nillable.js create mode 100644 src/main/resources/templates/soap2api/remove-nillable.xml diff --git a/src/main/resources/templates/soap2api/remove-nillable.js b/src/main/resources/templates/soap2api/remove-nillable.js new file mode 100644 index 0000000..92e8fc1 --- /dev/null +++ b/src/main/resources/templates/soap2api/remove-nillable.js @@ -0,0 +1,40 @@ +// js file used to traverse response content , find and replace nil:true +// ------------------------------------------------------------------ +var what = Object.prototype.toString; + +function walkObj(obj, fn) { + var wo = what.call(obj); + if (wo == "[object Object]") { + Object.keys(obj).forEach(function(key){ + fn(obj, key); + var item = obj[key], w = what.call(item); + if (w == "[object Object]" || w == "[object Array]") { + walkObj(item, fn); + } + }); + } + else if (wo == "[object Array]") { + obj.forEach(function(item, ix) { + fn(obj, ix); + }); + obj.forEach(function(item, ix) { + var w = what.call(item); + if (w == "[object Object]" || w == "[object Array]") { + walkObj(item, fn); + } + }); + } +} + +function checkAndFixNull(parent, key) { + var value = parent[key], w = what.call(value); + if ((w == "[object Object]") && (value.TEXT === null) && (value['@nil'] === true)) { + parent[key] = null; + } +} + +var source = JSON.parse(context.getVariable('response.content')); +walkObj(source, checkAndFixNull); + +// source now contains the transformed JSON hash +context.setVariable('response.content', JSON.stringify(source, null, 2)); \ No newline at end of file diff --git a/src/main/resources/templates/soap2api/remove-nillable.xml b/src/main/resources/templates/soap2api/remove-nillable.xml new file mode 100644 index 0000000..1a1334a --- /dev/null +++ b/src/main/resources/templates/soap2api/remove-nillable.xml @@ -0,0 +1,6 @@ + + + remove-nillable + + jsc://remove-nillable.js + \ No newline at end of file From bb5a231dec8a099ad67379a79b55a47f4cad53a3 Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Tue, 5 Jun 2018 19:45:38 -0400 Subject: [PATCH 11/26] Update targetDefault.xml added java script in target preflow response to resolve nillable issue . --- src/main/resources/templates/soap2api/targetDefault.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/resources/templates/soap2api/targetDefault.xml b/src/main/resources/templates/soap2api/targetDefault.xml index ff6d04a..60ae4db 100644 --- a/src/main/resources/templates/soap2api/targetDefault.xml +++ b/src/main/resources/templates/soap2api/targetDefault.xml @@ -16,6 +16,9 @@ xml-to-json (verb != "GET" AND contentformat == "application/json") OR (verb == "GET" AND acceptformat !~ "*/xml") + + remove-nillable + get-response-soap-body (verb != "GET" AND contentformat == "application/json") OR (verb == "GET" AND acceptformat !~ "*/xml") @@ -68,4 +71,4 @@ https://example.com/ - \ No newline at end of file + From 95de204ad6ba1b670e245248805d47dcd182df22 Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Wed, 6 Jun 2018 12:19:43 -0400 Subject: [PATCH 12/26] Update GenerateProxy.java modified to add outer element for POST/PUT resources . flag changed to allowRespRootElement from showRespRootElement --- .../com/apigee/proxywriter/GenerateProxy.java | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index a9ec37b..33a4fe2 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -170,7 +170,7 @@ public class GenerateProxy { // set this to true if allowSoapHeaders should be added to the proxy private boolean ALLOW_SOAP_HEADERS; - private boolean SHOW_RESP_ROOT_ELEMENT; + private boolean ALLOW_RESP_ROOT_ELEMENT; // fail safe measure when schemas are heavily nested or have 100s of // elements @@ -231,7 +231,7 @@ public class GenerateProxy { private String xpathNameSpace; private String xpathNameSpaceURI; - private boolean outputOASRootElement = false; + private boolean addRootElementToOAS = false; @@ -268,7 +268,7 @@ public GenerateProxy() { OAUTH = false; ALLOW_EMPTY_NODES = false; ALLOW_SOAP_HEADERS = false; - SHOW_RESP_ROOT_ELEMENT = false; + ALLOW_RESP_ROOT_ELEMENT = false; APIKEY = false; QUOTAAPIKEY = false; QUOTAOAUTH = false; @@ -354,8 +354,8 @@ public void setAllowSoapHeaders(boolean allowSoapHeaders) { ALLOW_SOAP_HEADERS = allowSoapHeaders; } - public void setShowRespRootElement(boolean showRespRootElement) { - SHOW_RESP_ROOT_ELEMENT = showRespRootElement; + public void setAllowRespRootElement(boolean allowRespRootElement) { + ALLOW_RESP_ROOT_ELEMENT = allowRespRootElement; } public String getTargetEndpoint() { @@ -1764,9 +1764,9 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js xpathNameSpace = e.getType().getPrefix(); xpathNameSpaceURI = e.getNamespaceUri(); - if(outputOASRootElement) { + if(addRootElementToOAS) { OASUtils.addObjectOutputRes(parent, parentName, e.getName(), true,e.getType().getLocalPart()); - outputOASRootElement = false; + addRootElementToOAS = false; }else { OASUtils.addObject(parent, parentName, e.getName(), true,e.getType().getLocalPart()); } @@ -2574,7 +2574,7 @@ private void getOASDefinitions(Definitions wsdl, com.predic8.schema.Element e) { JsonObject rootElement = OASUtils.createComplexType(e.getName(), e.getMinOccurs(), e.getMaxOccurs()); JsonObject tempRootElement = rootElement; JsonObject rootInnerElement; - if(outputOASRootElement) { + if(addRootElementToOAS) { rootInnerElement = OASUtils.createComplexTypeOP(e.getName(), rootElement); tempRootElement.add("properties", rootInnerElement); rootElement = tempRootElement; @@ -2993,6 +2993,11 @@ private String generateOAS() throws Exception { // TODO: handle 0 parts } else { com.predic8.schema.Element eInput = op.getInput().getMessage().getParts().get(0).getElement(); + if(!verb.equalsIgnoreCase("GET")) { + if(ALLOW_RESP_ROOT_ELEMENT) { + addRootElementToOAS = true; + } + } getOASDefinitions(wsdl, eInput); if (!verb.equalsIgnoreCase("GET")) { @@ -3000,6 +3005,7 @@ private String generateOAS() throws Exception { } else { parameters = OASUtils.getQueryParameters(queryParams); } + addRootElementToOAS = false; } queryParams.clear(); @@ -3009,13 +3015,13 @@ private String generateOAS() throws Exception { if (op.getOutput().getMessage().getParts().size() > 0) { com.predic8.schema.Element eOutput = op.getOutput().getMessage().getParts().get(0).getElement(); if (eOutput != null) { - if(SHOW_RESP_ROOT_ELEMENT) { - outputOASRootElement = true; + if(ALLOW_RESP_ROOT_ELEMENT) { + addRootElementToOAS = true; } getOASDefinitions(wsdl, eOutput); operationDetails.add("responses", OASUtils.getResponse(eOutput.getName())); } - outputOASRootElement = false; + addRootElementToOAS = false; } } } catch (Exception e) { @@ -3218,7 +3224,7 @@ public static void usage() { System.out.println("-debug= default is false"); System.out.println("-allowEmptyNodes= default is false; works only if it is set to true"); System.out.println("-allowSoapHeaders= default is false; works only if it is set to true"); - System.out.println("-showRespRootElement= default is false; works only if it is set to true"); + System.out.println("-allowRespRootElement= default is false; works only if it is set to true"); System.out.println(""); System.out.println(""); System.out.println("Examples:"); @@ -3339,8 +3345,8 @@ public static void main(String[] args) throws Exception { opt.getSet().addOption("allowEmptyNodes", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); // add allowSoapHeaders functionality opt.getSet().addOption("allowSoapHeaders", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); - // add showRespRootElement to show response root elements in OAS - opt.getSet().addOption("showRespRootElement", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); + // add allowRespRootElement to show response root elements in OAS + opt.getSet().addOption("allowRespRootElement", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); opt.check(); @@ -3428,8 +3434,8 @@ public static void main(String[] args) throws Exception { genProxy.setAllowSoapHeaders(new Boolean(opt.getSet().getOption("allowSoapHeaders").getResultValue(0))); } - if (opt.getSet().isSet("showRespRootElement")) { - genProxy.setShowRespRootElement(new Boolean(opt.getSet().getOption("showRespRootElement").getResultValue(0))); + if (opt.getSet().isSet("allowRespRootElement")) { + genProxy.setAllowRespRootElement(new Boolean(opt.getSet().getOption("allowRespRootElement").getResultValue(0))); } if (opt.getSet().isSet("apikey")) { From 51f76862f84400cfe539d15bfbb31ba3af6e6905 Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Wed, 6 Jun 2018 23:08:13 -0400 Subject: [PATCH 13/26] Update GenerateProxyTest.java modified to add newly added templates used to fix nillable issue --- .../apigee/proxywriter/GenerateProxyTest.java | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/src/test/java/com/apigee/proxywriter/GenerateProxyTest.java b/src/test/java/com/apigee/proxywriter/GenerateProxyTest.java index d9fbdc3..0a7e2f7 100644 --- a/src/test/java/com/apigee/proxywriter/GenerateProxyTest.java +++ b/src/test/java/com/apigee/proxywriter/GenerateProxyTest.java @@ -1,25 +1,19 @@ package com.apigee.proxywriter; -import com.apigee.proxywriter.exception.ErrorParsingWsdlException; -import com.apigee.utils.WsdlDefinitions; - -import org.junit.Assert; -import org.junit.Test; - -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; -import java.nio.file.CopyOption; -import java.nio.file.Files; -import java.nio.file.StandardCopyOption; import java.util.Arrays; import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import org.junit.Assert; +import org.junit.Test; + +import com.apigee.proxywriter.exception.ErrorParsingWsdlException; +import com.apigee.utils.WsdlDefinitions; + public class GenerateProxyTest { @@ -131,9 +125,11 @@ public void testGenerateRest() throws Exception { "apiproxy/policies/set-target-url.xml", "apiproxy/policies/unknown-resource-xml.xml", "apiproxy/policies/unknown-resource.xml", + "apiproxy/policies/remove-nillable.xml", "apiproxy/policies/xml-to-json.xml", "apiproxy/proxies/default.xml", "apiproxy/resources/jsc/root-wrapper.js", + "apiproxy/resources/jsc/remove-nillable.js", "apiproxy/resources/xsl/remove-empty-nodes.xslt", "apiproxy/resources/xsl/remove-namespaces.xslt", "apiproxy/targets/default.xml", @@ -309,7 +305,9 @@ public void testSelectedOperations () throws Exception { "apiproxy/policies/return-open-api.xml", "apiproxy/targets/default.xml", "apiproxy/proxies/default.xml", - "apiproxy/PayPalAPIInterfaceService.xml"); + "apiproxy/PayPalAPIInterfaceService.xml", + "apiproxy/resources/jsc/remove-nillable.js", + "apiproxy/policies/remove-nillable.xml"); final String PAYPAL_WSDL = "https://www.paypalobjects.com/wsdl/PayPalSvc.wsdl"; String jsonSelectedOp = "[{\"operationName\": \"AddressVerify\",\"verb\": \"post\",\"resourcePath\": \"/addressverify\"},{\"operationName\": \"MassPay\",\"verb\": \"put\",\"resourcePath\": \"/massivepay\"}]"; GenerateProxy genProxy = new GenerateProxy(); From 5f55775586b3c75ddbbc4089bf42155f1d6b62f2 Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Wed, 6 Jun 2018 23:27:31 -0400 Subject: [PATCH 14/26] Update GenerateProxyTest.java commented few test cases , need to analyze on that. --- .../com/apigee/proxywriter/GenerateProxyTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/apigee/proxywriter/GenerateProxyTest.java b/src/test/java/com/apigee/proxywriter/GenerateProxyTest.java index 0a7e2f7..a8db479 100644 --- a/src/test/java/com/apigee/proxywriter/GenerateProxyTest.java +++ b/src/test/java/com/apigee/proxywriter/GenerateProxyTest.java @@ -64,7 +64,7 @@ private int entryCount(InputStream inputStream) throws IOException { return count; } - @Test + /* @Test public void testGeneratePassthrough() throws Exception { final List filenames = Arrays.asList( "apiproxy/policies/Extract-Operation-Name.xml", @@ -92,8 +92,8 @@ public void testGeneratePassthrough() throws Exception { " local-name(/*)" + System.getProperty("line.separator") + " " + System.getProperty("line.separator") + " " + System.getProperty("line.separator") + - " local-name(/*/*[local-name() = 'Body'])" + System.getProperty("line.separator") + - " " + System.getProperty("line.separator") + + " local-name(/*///*[local-name() = 'Body'])" + System.getProperty("line.separator") + + /* " " + System.getProperty("line.separator") + " " + System.getProperty("line.separator") + " namespace-uri(/*)" + System.getProperty("line.separator") + " " + System.getProperty("line.separator") + @@ -103,8 +103,8 @@ public void testGeneratePassthrough() throws Exception { " " + System.getProperty("line.separator") + ""); } - - @Test +*/ +/* @Test public void testGenerateRest() throws Exception { final List filenames = Arrays.asList( "apiproxy/policies/extract-format.xml", @@ -158,7 +158,7 @@ public void testGenerateRest() throws Exception { " " + System.getProperty("line.separator") + ""); } - +*/ @Test public void testVHosts() throws Exception { URL url = this.getClass().getResource(WEATHER_WSDL); From ed158f7210f68891661b936412b9673ea741e629 Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Thu, 7 Jun 2018 21:23:01 -0400 Subject: [PATCH 15/26] Update GenerateProxyTest.java reverted commented test cases by fixing white space issue with xml comparisons --- .../apigee/proxywriter/GenerateProxyTest.java | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/test/java/com/apigee/proxywriter/GenerateProxyTest.java b/src/test/java/com/apigee/proxywriter/GenerateProxyTest.java index a8db479..58d3fe5 100644 --- a/src/test/java/com/apigee/proxywriter/GenerateProxyTest.java +++ b/src/test/java/com/apigee/proxywriter/GenerateProxyTest.java @@ -13,6 +13,8 @@ import com.apigee.proxywriter.exception.ErrorParsingWsdlException; import com.apigee.utils.WsdlDefinitions; +import org.custommonkey.xmlunit.DetailedDiff; +import org.custommonkey.xmlunit.XMLUnit; public class GenerateProxyTest { @@ -64,7 +66,7 @@ private int entryCount(InputStream inputStream) throws IOException { return count; } - /* @Test + @Test public void testGeneratePassthrough() throws Exception { final List filenames = Arrays.asList( "apiproxy/policies/Extract-Operation-Name.xml", @@ -81,7 +83,8 @@ public void testGeneratePassthrough() throws Exception { checkForFilesInBundle(filenames, inputStream); inputStream.reset(); final String extractVariablesPolicy = readZipFileEntry("apiproxy/policies/Extract-Operation-Name.xml", inputStream); - Assert.assertEquals(extractVariablesPolicy, "" + System.getProperty("line.separator") + + + String extractPolicyStr = "" + System.getProperty("line.separator") + "" + System.getProperty("line.separator") + " Extract Operation Name" + System.getProperty("line.separator") + " " + System.getProperty("line.separator") + @@ -92,8 +95,8 @@ public void testGeneratePassthrough() throws Exception { " local-name(/*)" + System.getProperty("line.separator") + " " + System.getProperty("line.separator") + " " + System.getProperty("line.separator") + - " local-name(/*///*[local-name() = 'Body'])" + System.getProperty("line.separator") + - /* " " + System.getProperty("line.separator") + + " local-name(/*/*[local-name() = 'Body'])" + System.getProperty("line.separator") + + " " + System.getProperty("line.separator") + " " + System.getProperty("line.separator") + " namespace-uri(/*)" + System.getProperty("line.separator") + " " + System.getProperty("line.separator") + @@ -101,10 +104,27 @@ public void testGeneratePassthrough() throws Exception { " local-name(//*[local-name() = 'Body']/*[1])" + System.getProperty("line.separator") + " " + System.getProperty("line.separator") + " " + System.getProperty("line.separator") + - ""); + ""; + assertXMLEquals(extractVariablesPolicy,extractPolicyStr); + + } + + /* + * to validate xml strings after removing white spaces + * + */ + public static void assertXMLEquals(String expectedXML, String actualXML) throws Exception { + XMLUnit.setIgnoreWhitespace(true); + XMLUnit.setIgnoreAttributeOrder(true); + + DetailedDiff diff = new DetailedDiff(XMLUnit.compareXML(expectedXML, actualXML)); + + List allDifferences = diff.getAllDifferences(); + Assert.assertEquals("Differences found: "+ diff.toString(), 0, allDifferences.size()); } -*/ -/* @Test + + + @Test public void testGenerateRest() throws Exception { final List filenames = Arrays.asList( "apiproxy/policies/extract-format.xml", @@ -143,7 +163,7 @@ public void testGenerateRest() throws Exception { checkForFilesInBundle(filenames, inputStream); inputStream.reset(); final String extractVariablesPolicy = readZipFileEntry("apiproxy/policies/extract-format.xml", inputStream); - Assert.assertEquals(extractVariablesPolicy, "" + System.getProperty("line.separator") + + String extractXmlStr = "" + System.getProperty("line.separator") + "" + System.getProperty("line.separator") + " Extract Format" + System.getProperty("line.separator") + " " + System.getProperty("line.separator") + @@ -156,9 +176,11 @@ public void testGenerateRest() throws Exception { " " + System.getProperty("line.separator") + " {verb}" + System.getProperty("line.separator") + " " + System.getProperty("line.separator") + - ""); + "" ; + + assertXMLEquals(extractVariablesPolicy,extractXmlStr); } -*/ + @Test public void testVHosts() throws Exception { URL url = this.getClass().getResource(WEATHER_WSDL); From fa80461c12573b608e5bcdf043e1a228f00c00bd Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Thu, 7 Jun 2018 21:24:44 -0400 Subject: [PATCH 16/26] Update pom.xml added xmlunit dependency to resolve white space issue with xml comparisons --- pom.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e23f35b..a325245 100644 --- a/pom.xml +++ b/pom.xml @@ -174,5 +174,10 @@ 4.11 test + + xmlunit + xmlunit + 1.6 + - \ No newline at end of file + From b25b5b1d732bfa72d8a41b10c2fab1bf7427f030 Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Sun, 10 Jun 2018 09:58:41 -0400 Subject: [PATCH 17/26] Update GenerateProxy.java modified to resolve empty headers from wsdl --- .../com/apigee/proxywriter/GenerateProxy.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index 33a4fe2..dd38699 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -980,11 +980,15 @@ private void writeSOAP2APIAMPoliciesForPOST(Document assignTemplate, String oper // APIMap apiMap = messageTemplates.get(operationName); Document operationPayload = null; - String soapHeaderXMLFirst = ""; + String soapHeaderXMLStart = ""; String soapHeaderXMLEnd = "{soapBodyFromXSL}"; - soapHeader = soapHeaderXMLFirst+soapHeader+soapHeaderXMLEnd; + if(soapHeader != null && !soapHeader.equalsIgnoreCase("")) { + soapHeader = soapHeaderXMLStart+soapHeader+soapHeaderXMLEnd; + }else { + soapHeader = soapHeaderXMLStart+soapHeaderXMLEnd; + } // edgeui-654 (check for getBytes().length if (xmlUtils.isValidXML(soapHeader) && soapHeader.getBytes().length < 4096) { // JIRA-EDGEUI-672 @@ -2926,9 +2930,12 @@ private void parseWSDL() throws Exception { private String retrieveSoapHeaderFromEnvolope(String soapString) { // TODO Auto-generated method stub - - String soapHeaderStr = soapString.substring(soapString.indexOf(""),soapString.indexOf("")+"".length()+1); - soapHeaderStr = soapHeaderStr.replaceAll("s11", "soapenv"); + String soapHeaderStr = ""; + if(soapString != null && soapString.indexOf("") > 0 ) { + soapHeaderStr = soapString.substring(soapString.indexOf(""),soapString.indexOf("")+"".length()+1); + soapHeaderStr = soapHeaderStr.replaceAll("s11", "soapenv"); + return soapHeaderStr; + } return soapHeaderStr; } From 097cf19dc850a18b79a38e24fa07965d7183e68d Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Mon, 11 Jun 2018 09:07:59 -0400 Subject: [PATCH 18/26] Update GenerateProxy.java modified to resolve issue around transformation of Array elements which have Complex and Simple types --- .../com/apigee/proxywriter/GenerateProxy.java | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index dd38699..6ea72a6 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -96,6 +96,9 @@ public class GenerateProxy { private static final List primitiveTypes = Arrays.asList(new String[] { "int", "string", "boolean", "decimal", "float", "double", "duration", "dateTime", "time", "date", "long", "gYearMonth", "gYear", "gMonthDay", "gDay", "gMonth", "hexBinary", "base64Binary", "anyURI", "QName", "NOTATION" }); + private static final List primitiveArrayTypes = Arrays.asList(new String[] {"arrayofint","arrayoffloat","arrayofstring", + "arrayoflong","arrayofdouble"}); + private final String soap11Namespace = " xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "; //" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "; @@ -192,8 +195,6 @@ public class GenerateProxy { private String wsdlContent; - private String selectedOperationsJson; - private List vHosts; private SelectedOperations selectedOperations; @@ -233,7 +234,8 @@ public class GenerateProxy { private boolean addRootElementToOAS = false; - + private String subArrayElement=""; + // initialize the logger @@ -1747,6 +1749,7 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js } JsonObject properties = parent.getAsJsonObject("properties"); properties.add(e.getName(), restriction); + definitions.add(e.getName(), restriction); LOGGER.info("Parent=="+parent); return; } @@ -1763,12 +1766,23 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js TypeDefinition typeDefinition = getTypeFromSchema(e.getType(), schemas); if (typeDefinition instanceof ComplexType) { ComplexType ct = (ComplexType) typeDefinition; - JsonObject rootElement = OASUtils.createComplexType(e.getName(), e.getMinOccurs(), - e.getMaxOccurs()); + JsonObject rootElement; + if(e.getName().equalsIgnoreCase(subArrayElement)) { + rootElement = OASUtils.createComplexTypeRep(e.getName(), e.getMinOccurs(), + e.getMaxOccurs()); + addRootElementToOAS=false; + }else { + rootElement = OASUtils.createComplexType(e.getName(), e.getMinOccurs(), + e.getMaxOccurs()); + } xpathNameSpace = e.getType().getPrefix(); xpathNameSpaceURI = e.getNamespaceUri(); - - if(addRootElementToOAS) { + if(isCustomArrayType(e.getType().getLocalPart())) { + subArrayElement = e.getType().getLocalPart().toString().substring(e.getType().getLocalPart().toString().toLowerCase().indexOf("arrayof")+7, + e.getType().getLocalPart().toString().length()); + OASUtils.addObjectOutputArrayProp(parent, parentName, e.getName(), true,e.getType().getLocalPart(),subArrayElement); + OASUtils.addObjectOutputForArray(parent, parentName, e.getName(), true,e.getType().getLocalPart(),subArrayElement); + }else if(addRootElementToOAS) { OASUtils.addObjectOutputRes(parent, parentName, e.getName(), true,e.getType().getLocalPart()); addRootElementToOAS = false; }else { @@ -1782,6 +1796,19 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js } } + private boolean isCustomArrayType(String localPart) { + // TODO Auto-generated method stub + + if(localPart.toLowerCase().contains("arrayof")) { + if(primitiveArrayTypes.contains(localPart.toLowerCase())) { + return false; + }else { + return true; + } + } + return false; + } + private void parseElement(com.predic8.schema.Element e, List schemas, String rootElement, String rootNamespace, String rootPrefix) { if (e.getName() == null) { @@ -1843,7 +1870,6 @@ private com.predic8.schema.Element elementFromSchema(String name, List s } private void parseSchema(SchemaComponent sc, List schemas, String rootElementName, JsonObject rootElement) { - // fail safe measure. if (Thread.currentThread().getStackTrace().length >= 128) { TOO_MANY = true; @@ -1854,6 +1880,7 @@ else if (sc instanceof Sequence) { Sequence seq = (Sequence) sc; for (com.predic8.schema.Element e : seq.getElements()) { if (e.getType() != null) { + LOGGER.info("e.getType().getLocalPart()= "+e.getType().getLocalPart()+" max occurs "+e.getMaxOccurs()+ " min occurs"+e.getMinOccurs()); if (isPrimitive(e.getType().getLocalPart())) { if (rootElement == null) { rootElement = OASUtils.createComplexType(e.getName(), e.getMinOccurs(), e.getMaxOccurs()); From dd6a67e70b20abfbaae3efd05b0a47b5d674bbd7 Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Mon, 11 Jun 2018 09:09:16 -0400 Subject: [PATCH 19/26] Update OASUtils.java added supporting methods to resolve issue with array elements transformation in Open API Spec --- src/main/java/com/apigee/oas/OASUtils.java | 68 ++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/main/java/com/apigee/oas/OASUtils.java b/src/main/java/com/apigee/oas/OASUtils.java index 3b4c262..a239983 100644 --- a/src/main/java/com/apigee/oas/OASUtils.java +++ b/src/main/java/com/apigee/oas/OASUtils.java @@ -127,8 +127,66 @@ public static void addObjectOutputRes(JsonObject parent, String parentName, Stri object.addProperty("$ref", "#/definitions/"+qNameLocal); } properties.add(objectName, object); + + } + /* + * inorder to retrieve inner properties attribute to assign output elements + * + */ + public static void addObjectOutputArrayProp(JsonObject parent, String parentName, String objectName, + boolean isChildComplexType, String qNameLocal, String subArrayElement) { + + if(null != parent.getAsJsonObject("properties").getAsJsonObject(parentName)) { + + JsonObject properties = parent.getAsJsonObject("properties").getAsJsonObject(parentName).getAsJsonObject("properties"); + JsonObject innerProp = new JsonObject(); + JsonObject subArrayJson = new JsonObject(); + innerProp.add(subArrayElement, subArrayJson); + + JsonObject jsoonOuterProp = new JsonObject(); + jsoonOuterProp.add("properties", innerProp); + jsoonOuterProp.addProperty("type", "object"); + properties.add(objectName, jsoonOuterProp); + }else { + JsonObject properties = parent.getAsJsonObject("properties"); + JsonObject innerProp = new JsonObject(); + JsonObject subArrayJson = new JsonObject(); + innerProp.add(subArrayElement, subArrayJson); + + JsonObject jsoonOuterProp = new JsonObject(); + jsoonOuterProp.add("properties", innerProp); + jsoonOuterProp.addProperty("type", "object"); + properties.add(objectName, jsoonOuterProp); + } + } + + /* + * inorder to retrieve inner properties attribute to assign output elements + * + */ + public static void addObjectOutputForArray(JsonObject parent, String parentName, String objectName, + boolean isChildComplexType, String qNameLocal, String subArrayElement) { + + if(null != parent.getAsJsonObject("properties").getAsJsonObject(parentName)) { + JsonObject rep = parent.getAsJsonObject("properties").getAsJsonObject(parentName).getAsJsonObject("properties"). + getAsJsonObject(objectName).getAsJsonObject("properties").getAsJsonObject(subArrayElement); + JsonObject items = new JsonObject(); + + items.addProperty("$ref", "#/definitions/"+subArrayElement); + rep.add("items", items); + rep.addProperty("type", "array"); + }else { + JsonObject rep = parent.getAsJsonObject("properties").getAsJsonObject(objectName).getAsJsonObject("properties"). + getAsJsonObject(subArrayElement); + JsonObject items = new JsonObject(); + + items.addProperty("$ref", "#/definitions/"+subArrayElement); + rep.add("items", items); + rep.addProperty("type", "array"); + } + } public static JsonObject createComplexType(String name, String min, String max) { JsonObject complexType = new JsonObject(); @@ -160,6 +218,16 @@ public static JsonObject createComplexType(String name, String min, String max) } return complexType; } + + public static JsonObject createComplexTypeRep(String name, String min, String max) { + JsonObject complexType = new JsonObject(); + JsonObject properties = new JsonObject(); + complexType.add("properties", properties); + + complexType.addProperty("type", "object"); + return complexType; + } + public static JsonObject createExtension(String baseName) { JsonObject extension = new JsonObject(); From a40a2091103602a7ee2da847bf48e114654c441b Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Mon, 11 Jun 2018 09:48:06 -0400 Subject: [PATCH 20/26] Update GenerateProxy.java modified to resolve issue with transformation of child enum array which is of restriction type --- .../java/com/apigee/proxywriter/GenerateProxy.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index 6ea72a6..885b3c7 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -1736,17 +1736,15 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js com.predic8.schema.restriction.BaseRestriction baseRestriction = simpleType.getRestriction(); if(baseRestriction != null && baseRestriction.getBase().getLocalPart().equals("string")) { - JsonObject restriction = OASUtils.createRestriction(baseRestriction.getBase().getLocalPart(), e.getMinOccurs(), e.getMaxOccurs()); - JsonArray enumArray = null; - if(restriction.get("items")==null) - enumArray = (JsonArray)restriction.get("enum"); - else - enumArray = (JsonArray)((JsonObject)restriction.get("items")).get("enum"); - + JsonObject restriction = new JsonObject(); + //OASUtils.createRestriction(baseRestriction.getBase().getLocalPart(), e.getMinOccurs(), e.getMaxOccurs()); + JsonArray enumArray = new JsonArray(); for (com.predic8.schema.restriction.facet.EnumerationFacet en : baseRestriction.getEnumerationFacets()) { LOGGER.info("Restriction value =="+en.getValue()); enumArray.add(new JsonPrimitive(en.getValue())); } + restriction.add("enum", enumArray); + restriction.addProperty("type", "string"); JsonObject properties = parent.getAsJsonObject("properties"); properties.add(e.getName(), restriction); definitions.add(e.getName(), restriction); From 535a494ae977a7c08647d65ae4646b6b44fac327 Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Mon, 11 Jun 2018 19:41:55 -0400 Subject: [PATCH 21/26] Update GenerateProxy.java required flag is set to true for attributes whose min and max occurs are 1 in WSDL --- .../java/com/apigee/proxywriter/GenerateProxy.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index 885b3c7..970f3bf 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -97,7 +97,7 @@ public class GenerateProxy { "decimal", "float", "double", "duration", "dateTime", "time", "date", "long", "gYearMonth", "gYear", "gMonthDay", "gDay", "gMonth", "hexBinary", "base64Binary", "anyURI", "QName", "NOTATION" }); private static final List primitiveArrayTypes = Arrays.asList(new String[] {"arrayofint","arrayoffloat","arrayofstring", - "arrayoflong","arrayofdouble"}); + "arrayoflong","arrayofdouble","arrayofinteger"}); private final String soap11Namespace = " xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" "; //" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "; @@ -1736,8 +1736,7 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js com.predic8.schema.restriction.BaseRestriction baseRestriction = simpleType.getRestriction(); if(baseRestriction != null && baseRestriction.getBase().getLocalPart().equals("string")) { - JsonObject restriction = new JsonObject(); - //OASUtils.createRestriction(baseRestriction.getBase().getLocalPart(), e.getMinOccurs(), e.getMaxOccurs()); + JsonObject restriction = new JsonObject(); //OASUtils.createRestriction(baseRestriction.getBase().getLocalPart(), e.getMinOccurs(), e.getMaxOccurs()); JsonArray enumArray = new JsonArray(); for (com.predic8.schema.restriction.facet.EnumerationFacet en : baseRestriction.getEnumerationFacets()) { LOGGER.info("Restriction value =="+en.getValue()); @@ -1877,6 +1876,7 @@ private void parseSchema(SchemaComponent sc, List schemas, String rootEl else if (sc instanceof Sequence) { Sequence seq = (Sequence) sc; for (com.predic8.schema.Element e : seq.getElements()) { + if (e.getType() != null) { LOGGER.info("e.getType().getLocalPart()= "+e.getType().getLocalPart()+" max occurs "+e.getMaxOccurs()+ " min occurs"+e.getMinOccurs()); if (isPrimitive(e.getType().getLocalPart())) { @@ -1888,7 +1888,8 @@ else if (sc instanceof Sequence) { JsonObject properties = rootElement.getAsJsonObject("properties"); properties.add(e.getName(), OASUtils.createSimpleType(e.getType().getLocalPart(), e.getMinOccurs(), e.getMaxOccurs())); - queryParams.add(e.getName()); + + queryParams.add(OASUtils.manipulateQueryParams(e.getName(),e.getMinOccurs(), e.getMaxOccurs())); } else { parseElement(e, schemas, rootElement, rootElementName); } @@ -1909,7 +1910,7 @@ else if (sc instanceof Sequence) { JsonObject properties = rootElement.getAsJsonObject("properties"); properties.add(e.getName(), OASUtils.createSimpleType(e.getType().getLocalPart(), e.getMinOccurs(), e.getMaxOccurs())); - queryParams.add(e.getName()); + queryParams.add(OASUtils.manipulateQueryParams(e.getName(),e.getMinOccurs(), e.getMaxOccurs())); } } else { parseElement(e, schemas, rootElement, rootElementName); @@ -1969,6 +1970,7 @@ private void parseExtension(SchemaComponent sc,List schemas, String root definitions.add(name, extension); LOGGER.info("rootElementName=="+rootElementName+"JsonObject rootElement object=="+rootElement); } + private void parseSequence(Sequence seq, List schemas, String rootElementName,JsonObject rootElement) { for (com.predic8.schema.Element e : seq.getElements()) { @@ -2117,7 +2119,7 @@ private void parseParts(List parts, List schemas, String rootEleme JsonObject properties = rootElement.getAsJsonObject("properties"); properties.add(part.getName(), OASUtils.createSimpleType(part.getType().getQname().getLocalPart(), "0", "1")); - queryParams.add(part.getName()); + queryParams.add(OASUtils.manipulateQueryParams(part.getName(),"0", "1")); } else { TypeDefinition typeDefinition = part.getType(); if (typeDefinition instanceof ComplexType) { From b439b061a204ad4551a7d70fc7c9640596c14c59 Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Mon, 11 Jun 2018 19:43:56 -0400 Subject: [PATCH 22/26] Update OASUtils.java required flag is set to true for attributes whose min and max occurs are 1 in WSDL --- src/main/java/com/apigee/oas/OASUtils.java | 25 ++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/apigee/oas/OASUtils.java b/src/main/java/com/apigee/oas/OASUtils.java index a239983..93bca56 100644 --- a/src/main/java/com/apigee/oas/OASUtils.java +++ b/src/main/java/com/apigee/oas/OASUtils.java @@ -71,9 +71,15 @@ public static JsonArray getQueryParameters(ArrayList queryParams) { JsonObject parameter = null; for (String queryParam : queryParams) { parameter = new JsonObject(); - parameter.addProperty("name", queryParam); + String paramSplit[] = queryParam.split("_"); + parameter.addProperty("name", paramSplit[0]); parameter.addProperty("in", "query"); - parameter.addProperty("required", false); + if(paramSplit.length>1) { + parameter.addProperty("required", Boolean.valueOf(paramSplit[1])); + }else { + parameter.addProperty("required",false); + } + parameter.addProperty("type", "string"); parameters.add(parameter); } @@ -332,5 +338,20 @@ public static JsonObject createSimpleType(String type, String min, String max) { return simpleType; } + public static String manipulateQueryParams(String name, String min, String max) { + + String queryParamStr = ""; + String required = "false"; + if (max.equalsIgnoreCase("unbounded")) { + max = "-1"; + } + if(Integer.parseInt(min) ==1 && Integer.parseInt(max) ==1) { + required = "true"; + } + + queryParamStr = queryParamStr.concat(name+"_"+required); + return queryParamStr; + } + } From 2e762fde8a632df2c931ecdd14955f8489074b5b Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Thu, 14 Jun 2018 12:23:15 -0400 Subject: [PATCH 23/26] Update GenerateProxy.java modified to capture array instances and pass it to TreatAsArray option inside xmltojson policy. flag added is allowTreatAsArray=true --- .../com/apigee/proxywriter/GenerateProxy.java | 147 +++++++++++++++++- 1 file changed, 141 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index 970f3bf..14c0b57 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -113,6 +113,7 @@ public class GenerateProxy { private static final String SOAP2API_APIPROXY_TEMPLATE = "/templates/soap2api/apiProxyTemplate.xml"; private static final String SOAP2API_PROXY_TEMPLATE = "/templates/soap2api/proxyDefault.xml"; + private static final String SOAP2API_TARGET_TEMPLATE = "/templates/soap2api/targetDefault.xml"; private static final String SOAP2API_EXTRACT_TEMPLATE = "/templates/soap2api/ExtractPolicy.xml"; @@ -135,6 +136,8 @@ public class GenerateProxy { private static final String SOAPPASSTHRU_PROXY_TEMPLATE = "/templates/soappassthru/proxyDefault.xml"; private static final String SOAPPASSTHRU_TARGET_TEMPLATE = "/templates/soappassthru/targetDefault.xml"; private static final String SOAPPASSTHRU_GETWSDL_TEMPLATE = "/templates/soappassthru/return-wsdl.xml"; + + private static final String SOAP2API_XML_TO_JSON_TREAT_AS_ARRAY = "/templates/soap2api/xml-to-json.xml"; private static final String OAS_TEMPLATE = "/templates/oas/oastemplate.json"; @@ -174,6 +177,8 @@ public class GenerateProxy { private boolean ALLOW_SOAP_HEADERS; private boolean ALLOW_RESP_ROOT_ELEMENT; + + private boolean ALLOW_TREAT_AS_ARRAY; // fail safe measure when schemas are heavily nested or have 100s of // elements @@ -236,6 +241,11 @@ public class GenerateProxy { private String subArrayElement=""; + private StringBuffer treatAsArrayStr= new StringBuffer(); + + private boolean treatAsArrayForOutput = false; + + private List treatAsArrayList = new ArrayList(); // initialize the logger @@ -271,6 +281,7 @@ public GenerateProxy() { ALLOW_EMPTY_NODES = false; ALLOW_SOAP_HEADERS = false; ALLOW_RESP_ROOT_ELEMENT = false; + ALLOW_TREAT_AS_ARRAY = false; APIKEY = false; QUOTAAPIKEY = false; QUOTAOAUTH = false; @@ -360,6 +371,10 @@ public void setAllowRespRootElement(boolean allowRespRootElement) { ALLOW_RESP_ROOT_ELEMENT = allowRespRootElement; } + public void setAllowTreatAsArray(boolean allowTreatAsArray) { + ALLOW_TREAT_AS_ARRAY = allowTreatAsArray; + } + public String getTargetEndpoint() { return targetEndpoint; } @@ -1401,9 +1416,13 @@ private void writeStdPolicies() throws Exception { * java.nio.file.StandardCopyOption.REPLACE_EXISTING); */ } else { + + + sourcePath += "soap2api/"; - Files.copy(getClass().getResourceAsStream(sourcePath + "xml-to-json.xml"), - Paths.get(targetPath + "xml-to-json.xml"), java.nio.file.StandardCopyOption.REPLACE_EXISTING); + if(!ALLOW_TREAT_AS_ARRAY) + Files.copy(getClass().getResourceAsStream(sourcePath + "xml-to-json.xml"), + Paths.get(targetPath + "xml-to-json.xml"), java.nio.file.StandardCopyOption.REPLACE_EXISTING); Files.copy(getClass().getResourceAsStream(sourcePath + "set-response-soap-body.xml"), Paths.get(targetPath + "set-response-soap-body.xml"), java.nio.file.StandardCopyOption.REPLACE_EXISTING); @@ -1505,6 +1524,36 @@ private void writeStdPolicies() throws Exception { }.getClass().getEnclosingMethod().getName()); } + private void modifyXMLtoJSONForTreatASArray(List treatAsArrayList2) throws Exception { + // TODO Auto-generated method stub + + Document xmltoJsonDoc; + XMLUtils xmlUtils = new XMLUtils(); + xmltoJsonDoc = xmlUtils.readXML(SOAP2API_XML_TO_JSON_TREAT_AS_ARRAY); + + Node optionsNode = xmltoJsonDoc.getElementsByTagName("Options").item(0); + + Element treatAsArray = xmltoJsonDoc.createElement("TreatAsArray"); + if(treatAsArrayList2 != null && treatAsArrayList2.size() > 0) { + for(String arrayStr : treatAsArrayList2) { + Element Path = xmltoJsonDoc.createElement("Path"); + Path.setAttribute("unwrap", "true"); + Path.setTextContent("Envelope/Body/"+arrayStr); + treatAsArray.appendChild(Path); + } + + } + optionsNode.appendChild(treatAsArray); + + xmlUtils.writeXML(xmltoJsonDoc, buildFolder + File.separator + "apiproxy" + File.separator + "policies" + + File.separator + "xml-tojson" + ".xml"); + LOGGER.exiting(GenerateProxy.class.getName(), new Object() { + }.getClass().getEnclosingMethod().getName()); + + + + } + private void writeSOAPPassThruProxyEndpointConditions(String proxyDescription) throws Exception { LOGGER.entering(GenerateProxy.class.getName(), new Object() { }.getClass().getEnclosingMethod().getName()); @@ -1736,6 +1785,7 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js com.predic8.schema.restriction.BaseRestriction baseRestriction = simpleType.getRestriction(); if(baseRestriction != null && baseRestriction.getBase().getLocalPart().equals("string")) { + JsonObject restriction = new JsonObject(); //OASUtils.createRestriction(baseRestriction.getBase().getLocalPart(), e.getMinOccurs(), e.getMaxOccurs()); JsonArray enumArray = new JsonArray(); for (com.predic8.schema.restriction.facet.EnumerationFacet en : baseRestriction.getEnumerationFacets()) { @@ -1748,6 +1798,10 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js properties.add(e.getName(), restriction); definitions.add(e.getName(), restriction); LOGGER.info("Parent=="+parent); + + if(ALLOW_TREAT_AS_ARRAY) + manipulateTreatAsArrayEnums(treatAsArrayForOutput,enumArray,e.getName()); + return; } @@ -1761,9 +1815,14 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js parseSchema(ct.getModel(), schemas, e.getName(), rootElement); } else if (e.getType() != null) { TypeDefinition typeDefinition = getTypeFromSchema(e.getType(), schemas); + if (typeDefinition instanceof ComplexType) { ComplexType ct = (ComplexType) typeDefinition; JsonObject rootElement; + if(ALLOW_TREAT_AS_ARRAY && treatAsArrayForOutput) { + treatAsArrayStr.append("/"+e.getName()); + } + if(e.getName().equalsIgnoreCase(subArrayElement)) { rootElement = OASUtils.createComplexTypeRep(e.getName(), e.getMinOccurs(), e.getMaxOccurs()); @@ -1775,7 +1834,8 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js xpathNameSpace = e.getType().getPrefix(); xpathNameSpaceURI = e.getNamespaceUri(); if(isCustomArrayType(e.getType().getLocalPart())) { - subArrayElement = e.getType().getLocalPart().toString().substring(e.getType().getLocalPart().toString().toLowerCase().indexOf("arrayof")+7, + subArrayElement = e.getType().getLocalPart().toString(). + substring(e.getType().getLocalPart().toString().toLowerCase().indexOf("arrayof")+7, e.getType().getLocalPart().toString().length()); OASUtils.addObjectOutputArrayProp(parent, parentName, e.getName(), true,e.getType().getLocalPart(),subArrayElement); OASUtils.addObjectOutputForArray(parent, parentName, e.getName(), true,e.getType().getLocalPart(),subArrayElement); @@ -1793,6 +1853,50 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js } } + private void manipulateTreatAsArrayEnums(boolean treatAsArrayForOutput2, JsonArray enumArray, String name) { + // TODO Auto-generated method stub + StringBuffer tempStr = new StringBuffer(); + if(treatAsArrayForOutput2 && enumArray.getAsJsonArray().size() > 0) { + + String str[] = treatAsArrayStr.toString().split("/"); + for(int i=0;i 0) + temp = tempStr.toString().substring(0, tempStr.length()-1); + treatAsArrayStr.append(temp); + + } + + } + + private void manipulateTreatAsArrayList(boolean treatAsArrayForOutput2, String name) { + // TODO Auto-generated method stub + if(treatAsArrayForOutput2) { + StringBuffer tempStr = new StringBuffer(); + String str[] = treatAsArrayStr.toString().split("/"); + for(int i=0;i 0) + temp = tempStr.toString().substring(0, tempStr.length()-1); + treatAsArrayStr.append(temp); + + } + + } + + private boolean isCustomArrayType(String localPart) { // TODO Auto-generated method stub @@ -1888,8 +1992,10 @@ else if (sc instanceof Sequence) { JsonObject properties = rootElement.getAsJsonObject("properties"); properties.add(e.getName(), OASUtils.createSimpleType(e.getType().getLocalPart(), e.getMinOccurs(), e.getMaxOccurs())); - queryParams.add(OASUtils.manipulateQueryParams(e.getName(),e.getMinOccurs(), e.getMaxOccurs())); + if(ALLOW_TREAT_AS_ARRAY && treatAsArrayForOutput && e.getMaxOccurs().toLowerCase().equalsIgnoreCase("unbounded")) { + manipulateTreatAsArrayList(treatAsArrayForOutput, e.getName()); + } } else { parseElement(e, schemas, rootElement, rootElementName); } @@ -2609,8 +2715,17 @@ private void getOASDefinitions(Definitions wsdl, com.predic8.schema.Element e) { rootInnerElement = OASUtils.createComplexTypeOP(e.getName(), rootElement); tempRootElement.add("properties", rootInnerElement); rootElement = tempRootElement; + } + if(treatAsArrayForOutput) { + treatAsArrayStr.append(e.getName()); + } +/* boolean test = false; + if(treatAsArrayStr.toString().contains("GetRepListResponse")) { + test = true; + } +*/ definitions.add(e.getName(), rootElement); parseSchema(ct.getModel(), wsdl.getSchemas(), e.getName(), rootElement); } @@ -2993,8 +3108,11 @@ private String generateOAS() throws Exception { PortType portType = binding.getPortType(); HashMap selectedOperationList = selectedOperations.getSelectedOperations(); + + for (Operation op : portType.getOperations()) { // the current operations is not in the list; skip. + if (selectedOperationList.size() > 0 && !selectedOperationList.containsKey(op.getName())) { continue; } @@ -3032,8 +3150,8 @@ private String generateOAS() throws Exception { addRootElementToOAS = true; } } + getOASDefinitions(wsdl, eInput); - if (!verb.equalsIgnoreCase("GET")) { parameters = OASUtils.getBodyParameter(eInput.getName()); } else { @@ -3052,6 +3170,11 @@ private String generateOAS() throws Exception { if(ALLOW_RESP_ROOT_ELEMENT) { addRootElementToOAS = true; } + if(ALLOW_TREAT_AS_ARRAY) { + treatAsArrayStr = new StringBuffer(); + treatAsArrayForOutput = true; + } + getOASDefinitions(wsdl, eOutput); operationDetails.add("responses", OASUtils.getResponse(eOutput.getName())); } @@ -3062,7 +3185,7 @@ private String generateOAS() throws Exception { //Ignore any errors here. Just don't generate the OAS for this portion } } - + treatAsArrayForOutput = false; operationDetails.addProperty("description", "Implements WSDL operation " + op.getName()); operationDetails.add("parameters", parameters); @@ -3186,12 +3309,17 @@ public InputStream begin(String proxyDescription, String wsdlPath) throws Except if (!PASSTHRU) { LOGGER.info("Generated SOAP Message Templates."); writeSOAP2APIProxyEndpoint(proxyDescription); + if(ALLOW_TREAT_AS_ARRAY) { + LOGGER.info("Generate XML tOJSON Policy SOAP Message Templates."); + modifyXMLtoJSONForTreatASArray(treatAsArrayList); + } LOGGER.info("Generated proxies XML."); writeStdPolicies(); LOGGER.info("Copied standard policies."); writeTargetEndpoint(); LOGGER.info("Generated target XML."); } else { + writeStdPolicies(); LOGGER.info("Copied standard policies."); writeTargetEndpoint(); @@ -3259,6 +3387,7 @@ public static void usage() { System.out.println("-allowEmptyNodes= default is false; works only if it is set to true"); System.out.println("-allowSoapHeaders= default is false; works only if it is set to true"); System.out.println("-allowRespRootElement= default is false; works only if it is set to true"); + System.out.println("-allowTreatAsArray= default is false; works only if it is set to true"); System.out.println(""); System.out.println(""); System.out.println("Examples:"); @@ -3381,6 +3510,8 @@ public static void main(String[] args) throws Exception { opt.getSet().addOption("allowSoapHeaders", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); // add allowRespRootElement to show response root elements in OAS opt.getSet().addOption("allowRespRootElement", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); + // add allowTreatAsArray to show Path for attributes that are eligible as Array in xml-to-json policy + opt.getSet().addOption("allowTreatAsArray", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); opt.check(); @@ -3472,6 +3603,10 @@ public static void main(String[] args) throws Exception { genProxy.setAllowRespRootElement(new Boolean(opt.getSet().getOption("allowRespRootElement").getResultValue(0))); } + if (opt.getSet().isSet("allowTreatAsArray")) { + genProxy.setAllowTreatAsArray(new Boolean(opt.getSet().getOption("allowTreatAsArray").getResultValue(0))); + } + if (opt.getSet().isSet("apikey")) { genProxy.setAPIKey(new Boolean(opt.getSet().getOption("apikey").getResultValue(0))); if (opt.getSet().isSet("quota")) { From ac1c03cf6c797b968704299a2a9b7938d44e6cd7 Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Mon, 18 Jun 2018 09:58:04 -0400 Subject: [PATCH 24/26] Update GenerateProxy.java modified flag names as allowRespRootElement to enableRespRootElement and allowTreatAsArray - preserveArray allowSoapHeaders to enableSoapHeaders as per review comments Code fix to handle classcast exception while parsing complexcontent --- .../com/apigee/proxywriter/GenerateProxy.java | 119 +++++++++--------- 1 file changed, 63 insertions(+), 56 deletions(-) diff --git a/src/main/java/com/apigee/proxywriter/GenerateProxy.java b/src/main/java/com/apigee/proxywriter/GenerateProxy.java index 14c0b57..c003be6 100644 --- a/src/main/java/com/apigee/proxywriter/GenerateProxy.java +++ b/src/main/java/com/apigee/proxywriter/GenerateProxy.java @@ -170,15 +170,15 @@ public class GenerateProxy { private boolean RPCSTYLE; // enable this flag if user sets desc private boolean DESCSET; - // set this to true if allowEmptyNodes should be added to the proxy - private boolean ALLOW_EMPTY_NODES; + // set this to true if enableEmptyNodes should be added to the proxy + private boolean ENABLE_EMPTY_NODES; - // set this to true if allowSoapHeaders should be added to the proxy - private boolean ALLOW_SOAP_HEADERS; + // set this to true if enableSoapHeaders should be added to the proxy + private boolean ENABLE_SOAP_HEADERS; - private boolean ALLOW_RESP_ROOT_ELEMENT; + private boolean ENABLE_RESP_ROOT_ELEMENT; - private boolean ALLOW_TREAT_AS_ARRAY; + private boolean PRESERVE_ARRAY; // fail safe measure when schemas are heavily nested or have 100s of // elements @@ -278,10 +278,10 @@ public GenerateProxy() { ALLPOST = false; PASSTHRU = false; OAUTH = false; - ALLOW_EMPTY_NODES = false; - ALLOW_SOAP_HEADERS = false; - ALLOW_RESP_ROOT_ELEMENT = false; - ALLOW_TREAT_AS_ARRAY = false; + ENABLE_EMPTY_NODES = false; + ENABLE_SOAP_HEADERS = false; + ENABLE_RESP_ROOT_ELEMENT = false; + PRESERVE_ARRAY = false; APIKEY = false; QUOTAAPIKEY = false; QUOTAOAUTH = false; @@ -359,20 +359,20 @@ public void setOAuth(boolean oauth) { OAUTH = oauth; } - public void setAllowEmptyNodes(boolean allowEmptyNodes) { - ALLOW_EMPTY_NODES = allowEmptyNodes; + public void setEnableEmptyNodes(boolean enableEmptyNodes) { + ENABLE_EMPTY_NODES = enableEmptyNodes; } - public void setAllowSoapHeaders(boolean allowSoapHeaders) { - ALLOW_SOAP_HEADERS = allowSoapHeaders; + public void setEnableSoapHeaders(boolean enableSoapHeaders) { + ENABLE_SOAP_HEADERS = enableSoapHeaders; } - public void setAllowRespRootElement(boolean allowRespRootElement) { - ALLOW_RESP_ROOT_ELEMENT = allowRespRootElement; + public void setEnableRespRootElement(boolean enableRespRootElement) { + ENABLE_RESP_ROOT_ELEMENT = enableRespRootElement; } - public void setAllowTreatAsArray(boolean allowTreatAsArray) { - ALLOW_TREAT_AS_ARRAY = allowTreatAsArray; + public void setPreserveArray(boolean preserveArray) { + PRESERVE_ARRAY = preserveArray; } public String getTargetEndpoint() { @@ -694,7 +694,7 @@ private void writeSOAP2APIProxyEndpoint(String proxyDescription) throws Exceptio step2.appendChild(name2); request.appendChild(step2); - if(!ALLOW_EMPTY_NODES) { + if(!ENABLE_EMPTY_NODES) { if (apiMap.getJsonBody() != null) { step3 = proxyDefault.createElement("Step"); name3 = proxyDefault.createElement("Name"); @@ -729,7 +729,7 @@ private void writeSOAP2APIProxyEndpoint(String proxyDescription) throws Exceptio request.appendChild(step3); } - if(ALLOW_SOAP_HEADERS) { + if(ENABLE_SOAP_HEADERS) { step4 = proxyDefault.createElement("Step"); name4 = proxyDefault.createElement("Name"); name4.setTextContent(operationName+"-extract-from-xpath"); @@ -740,7 +740,7 @@ private void writeSOAP2APIProxyEndpoint(String proxyDescription) throws Exceptio // for soap 1.1 add soap action if (soapVersion.equalsIgnoreCase(SOAP_11)) { - if(!ALLOW_SOAP_HEADERS) { + if(!ENABLE_SOAP_HEADERS) { step5 = proxyDefault.createElement("Step"); name5 = proxyDefault.createElement("Name"); name5.setTextContent(addSoapAction); @@ -813,7 +813,7 @@ private void writeSOAP2APIProxyEndpoint(String proxyDescription) throws Exceptio writeAddNamespace(addNamespaceTemplate, operationName, false); } - if(ALLOW_SOAP_HEADERS) { + if(ENABLE_SOAP_HEADERS) { Node policy4 = apiTemplateDocument.createElement("Policy"); policy4.setTextContent(operationName+"Extract-from-xpath"); policies.appendChild(policy4); @@ -825,7 +825,7 @@ private void writeSOAP2APIProxyEndpoint(String proxyDescription) throws Exceptio if (soapVersion.equalsIgnoreCase(SOAP_11)) { // Add policy to proxy.xml - if(!ALLOW_SOAP_HEADERS) { + if(!ENABLE_SOAP_HEADERS) { Node policy5 = apiTemplateDocument.createElement("Policy"); policy5.setTextContent(addSoapAction); policies.appendChild(policy5); @@ -1420,7 +1420,7 @@ private void writeStdPolicies() throws Exception { sourcePath += "soap2api/"; - if(!ALLOW_TREAT_AS_ARRAY) + if(!PRESERVE_ARRAY) Files.copy(getClass().getResourceAsStream(sourcePath + "xml-to-json.xml"), Paths.get(targetPath + "xml-to-json.xml"), java.nio.file.StandardCopyOption.REPLACE_EXISTING); Files.copy(getClass().getResourceAsStream(sourcePath + "set-response-soap-body.xml"), @@ -1526,6 +1526,8 @@ private void writeStdPolicies() throws Exception { private void modifyXMLtoJSONForTreatASArray(List treatAsArrayList2) throws Exception { // TODO Auto-generated method stub + LOGGER.entering(GenerateProxy.class.getName(), new Object() { + }.getClass().getEnclosingMethod().getName()); Document xmltoJsonDoc; XMLUtils xmlUtils = new XMLUtils(); @@ -1799,7 +1801,7 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js definitions.add(e.getName(), restriction); LOGGER.info("Parent=="+parent); - if(ALLOW_TREAT_AS_ARRAY) + if(PRESERVE_ARRAY) manipulateTreatAsArrayEnums(treatAsArrayForOutput,enumArray,e.getName()); return; @@ -1819,7 +1821,7 @@ private void parseElement(com.predic8.schema.Element e, List schemas, Js if (typeDefinition instanceof ComplexType) { ComplexType ct = (ComplexType) typeDefinition; JsonObject rootElement; - if(ALLOW_TREAT_AS_ARRAY && treatAsArrayForOutput) { + if(PRESERVE_ARRAY && treatAsArrayForOutput) { treatAsArrayStr.append("/"+e.getName()); } @@ -1993,7 +1995,7 @@ else if (sc instanceof Sequence) { properties.add(e.getName(), OASUtils.createSimpleType(e.getType().getLocalPart(), e.getMinOccurs(), e.getMaxOccurs())); queryParams.add(OASUtils.manipulateQueryParams(e.getName(),e.getMinOccurs(), e.getMaxOccurs())); - if(ALLOW_TREAT_AS_ARRAY && treatAsArrayForOutput && e.getMaxOccurs().toLowerCase().equalsIgnoreCase("unbounded")) { + if(PRESERVE_ARRAY && treatAsArrayForOutput && e.getMaxOccurs().toLowerCase().equalsIgnoreCase("unbounded")) { manipulateTreatAsArrayList(treatAsArrayForOutput, e.getName()); } } else { @@ -2069,8 +2071,13 @@ private void parseExtension(SchemaComponent sc,List schemas, String root Derivation extElement = ((ComplexContent) sc).getDerivation(); LOGGER.info("derivation in parseExtension"+extElement.getModel().getAsString()); TypeDefinition typeDefinition = getTypeFromSchema(((ComplexContent) sc).getDerivation().getBase(), schemas); - Sequence seqBase = (Sequence) ((ComplexType) typeDefinition).getModel(); - parseSequence(seqBase,schemas,name,extension); + + + if(!(((ComplexType) typeDefinition).getModel() instanceof ComplexContent)) { + Sequence seqBase = (Sequence) ((ComplexType) typeDefinition).getModel(); + parseSequence(seqBase,schemas,name,extension); + } + Sequence seq = (Sequence) extElement.getModel(); parseSequence(seq,schemas,name,extension); definitions.add(name, extension); @@ -2968,7 +2975,7 @@ private void parseWSDL() throws Exception { TypeDefinition typeDefinition = null; KeyValue kv = null; - if(ALLOW_SOAP_HEADERS) { + if(ENABLE_SOAP_HEADERS) { creator.setCreator(new RequestTemplateCreator()); creator.createRequest(port.getName(), op.getName(), binding.getName()); @@ -3007,7 +3014,7 @@ private void parseWSDL() throws Exception { xmlUtils.generateOtherNamespacesXSLT(SOAP2API_XSL, op.getName(), rs.getTransform(soapVersion), namespace); ruleList.clear(); - if(!ALLOW_SOAP_HEADERS) { + if(!ENABLE_SOAP_HEADERS) { apiMap = new APIMap("", "", resourcePath, verb, requestElement.getName(), true); }else { @@ -3015,7 +3022,7 @@ private void parseWSDL() throws Exception { requestElement.getName(), false); } } else { - if(!ALLOW_SOAP_HEADERS) { + if(!ENABLE_SOAP_HEADERS) { apiMap = new APIMap("", "", resourcePath, verb, requestElement.getName(), false); }else { @@ -3146,7 +3153,7 @@ private String generateOAS() throws Exception { } else { com.predic8.schema.Element eInput = op.getInput().getMessage().getParts().get(0).getElement(); if(!verb.equalsIgnoreCase("GET")) { - if(ALLOW_RESP_ROOT_ELEMENT) { + if(ENABLE_RESP_ROOT_ELEMENT) { addRootElementToOAS = true; } } @@ -3167,10 +3174,10 @@ private String generateOAS() throws Exception { if (op.getOutput().getMessage().getParts().size() > 0) { com.predic8.schema.Element eOutput = op.getOutput().getMessage().getParts().get(0).getElement(); if (eOutput != null) { - if(ALLOW_RESP_ROOT_ELEMENT) { + if(ENABLE_RESP_ROOT_ELEMENT) { addRootElementToOAS = true; } - if(ALLOW_TREAT_AS_ARRAY) { + if(PRESERVE_ARRAY) { treatAsArrayStr = new StringBuffer(); treatAsArrayForOutput = true; } @@ -3309,7 +3316,7 @@ public InputStream begin(String proxyDescription, String wsdlPath) throws Except if (!PASSTHRU) { LOGGER.info("Generated SOAP Message Templates."); writeSOAP2APIProxyEndpoint(proxyDescription); - if(ALLOW_TREAT_AS_ARRAY) { + if(PRESERVE_ARRAY) { LOGGER.info("Generate XML tOJSON Policy SOAP Message Templates."); modifyXMLtoJSONForTreatASArray(treatAsArrayList); } @@ -3384,10 +3391,10 @@ public static void usage() { System.out.println("-basepath=specify base path"); System.out.println("-cors= default is false"); System.out.println("-debug= default is false"); - System.out.println("-allowEmptyNodes= default is false; works only if it is set to true"); - System.out.println("-allowSoapHeaders= default is false; works only if it is set to true"); - System.out.println("-allowRespRootElement= default is false; works only if it is set to true"); - System.out.println("-allowTreatAsArray= default is false; works only if it is set to true"); + System.out.println("-enableEmptyNodes= default is false; works only if it is set to true"); + System.out.println("-enableSoapHeaders= default is false; works only if it is set to true"); + System.out.println("-enableRespRootElement= default is false; works only if it is set to true"); + System.out.println("-preserveArray= default is false; works only if it is set to true"); System.out.println(""); System.out.println(""); System.out.println("Examples:"); @@ -3504,14 +3511,14 @@ public static void main(String[] args) throws Exception { opt.getSet().addOption("oas", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); // set this flag to enable debug opt.getSet().addOption("debug", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); - // add verify allowEmptyNodes policy - opt.getSet().addOption("allowEmptyNodes", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); - // add allowSoapHeaders functionality - opt.getSet().addOption("allowSoapHeaders", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); - // add allowRespRootElement to show response root elements in OAS - opt.getSet().addOption("allowRespRootElement", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); - // add allowTreatAsArray to show Path for attributes that are eligible as Array in xml-to-json policy - opt.getSet().addOption("allowTreatAsArray", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); + // add verify enableEmptyNodes policy + opt.getSet().addOption("enableEmptyNodes", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); + // add enableSoapHeaders functionality + opt.getSet().addOption("enableSoapHeaders", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); + // add enableRespRootElement to show response root elements in OAS + opt.getSet().addOption("enableRespRootElement", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); + // add enableTreatAsArray to show Path for attributes that are eligible as Array in xml-to-json policy + opt.getSet().addOption("preserveArray", Separator.EQUALS, Multiplicity.ZERO_OR_ONE); opt.check(); @@ -3591,20 +3598,20 @@ public static void main(String[] args) throws Exception { } } - if (opt.getSet().isSet("allowEmptyNodes")) { - genProxy.setAllowEmptyNodes(new Boolean(opt.getSet().getOption("allowEmptyNodes").getResultValue(0))); + if (opt.getSet().isSet("enableEmptyNodes")) { + genProxy.setEnableEmptyNodes(new Boolean(opt.getSet().getOption("enableEmptyNodes").getResultValue(0))); } - if (opt.getSet().isSet("allowSoapHeaders")) { - genProxy.setAllowSoapHeaders(new Boolean(opt.getSet().getOption("allowSoapHeaders").getResultValue(0))); + if (opt.getSet().isSet("enableSoapHeaders")) { + genProxy.setEnableSoapHeaders(new Boolean(opt.getSet().getOption("enableSoapHeaders").getResultValue(0))); } - if (opt.getSet().isSet("allowRespRootElement")) { - genProxy.setAllowRespRootElement(new Boolean(opt.getSet().getOption("allowRespRootElement").getResultValue(0))); + if (opt.getSet().isSet("enableRespRootElement")) { + genProxy.setEnableRespRootElement(new Boolean(opt.getSet().getOption("enableRespRootElement").getResultValue(0))); } - if (opt.getSet().isSet("allowTreatAsArray")) { - genProxy.setAllowTreatAsArray(new Boolean(opt.getSet().getOption("allowTreatAsArray").getResultValue(0))); + if (opt.getSet().isSet("preserveArray")) { + genProxy.setPreserveArray(new Boolean(opt.getSet().getOption("preserveArray").getResultValue(0))); } if (opt.getSet().isSet("apikey")) { From ba57aa415070d54bec60f4652c7e1ffe9f61a6f4 Mon Sep 17 00:00:00 2001 From: anilpaduchuri <32687608+anilpaduchuri@users.noreply.github.com> Date: Mon, 18 Jun 2018 10:03:00 -0400 Subject: [PATCH 25/26] Update README.MD 4 new flags have been added as part of wsdl2apigee tool enhancements. mentioned those details in write-up. These flags are used while creating proxy and OAS from provided WSDL. --- README.MD | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.MD b/README.MD index 1f6f367..18827a3 100644 --- a/README.MD +++ b/README.MD @@ -34,6 +34,10 @@ quota=false Works only if apikey or oauth is set basepath=Uses the basepath from the wsdl cors=false Don't enable CORS; Works only for SOAP to REST build=specify build folder default is temp folder; ensure user has access to read/write to temp folder +enableEmptyNodes= default is false; works only if it is set to true +enableSoapHeaders= default is false; works only if it is set to true +enableRespRootElement= default is false; works only if it is set to true +preserveArray= default is false; works only if it is set to true opsmap=specify operations map ``` ## Output From 94bc596aa7245b952d13b5956ab0bc5e4662e3d6 Mon Sep 17 00:00:00 2001 From: Abdul Kinadiyil Date: Sat, 7 Jul 2018 17:09:17 -0500 Subject: [PATCH 26/26] Modified the README file with details on additional options to run the java class --- README.MD | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.MD b/README.MD index 18827a3..14e47b9 100644 --- a/README.MD +++ b/README.MD @@ -19,7 +19,7 @@ java -jar wsdl2apigee-1.0.0-jar-with-dependencies.jar -wsdl= ### Other Options ``` -java -jar wsdl2apigee-1.0.0-jar-with-dependencies.jar -wsdl= -passthru= -desc= -allpost= -opsmap= -service= -port= -debug= -oauth= -vhosts=comma separated values for virtuals hosts> -build= -cors= -apikey= -quota= -basepath= +java -jar wsdl2apigee-1.0.0-jar-with-dependencies.jar -wsdl= -passthru= -desc= -allpost= -opsmap= -service= -port= -debug= -oauth= -vhosts=comma separated values for virtuals hosts> -build= -cors= -apikey= -quota= -basepath= -enableEmptyNodes= -enableSoapHeaders= -enableRespRootElement= -preserveArray= Defaults: passthru=false Do not convert to API/JSON. Treat as SOAP @@ -34,10 +34,10 @@ quota=false Works only if apikey or oauth is set basepath=Uses the basepath from the wsdl cors=false Don't enable CORS; Works only for SOAP to REST build=specify build folder default is temp folder; ensure user has access to read/write to temp folder -enableEmptyNodes= default is false; works only if it is set to true -enableSoapHeaders= default is false; works only if it is set to true -enableRespRootElement= default is false; works only if it is set to true -preserveArray= default is false; works only if it is set to true +enableEmptyNodes= default is false; Set to true if empty root element needs to be passed to target service as SOAP operation. +enableSoapHeaders= default is false; Set to true if SOAP headers need to be passed to target service. +enableRespRootElement= default is false; Set to true if XML root element from backend service needs to be mapped and sent as part of the JSON response. +preserveArray= default is false; Set to true if XML arrays in the WSDL needs to be mapped as JSON arrays in the response and OAS specification. This will set "TreatAsArray" option for the array Xpath in XML to JSON policy within the proxy. opsmap=specify operations map ``` ## Output