Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[10466] Fix for Missing headers in request body #245

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/WSDLObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class Operation {
this.style = '';
this.url = '';
this.input = '';
this.header = '';
this.output = '';
this.fault = '';
this.portName = '';
Expand Down
51 changes: 51 additions & 0 deletions lib/WsdlInformationService11.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const
ATTRIBUTE_PART = 'part',
XML_POLICY = 'http://schemas.xmlsoap.org/ws/2004/09/policy',
INPUT_TAG = 'input',
HEADER_TAG = 'header',
OUTPUT_TAG = 'output',
FAULT_TAG = 'fault',
MIME_CONTENT_TAG = 'mime:content',
Expand Down Expand Up @@ -90,6 +91,7 @@ class WsdlInformationService11 {
constructor() {
this.version = '1.1';
this.InputTagName = INPUT_TAG;
this.HeaderTagName = HEADER_TAG;
this.NameTag = NAME_TAG;
this.OutputTagName = OUTPUT_TAG;
this.FaultTagName = FAULT_TAG;
Expand Down Expand Up @@ -261,6 +263,55 @@ class WsdlInformationService11 {
return [];
}

/**
* finds the element from the port type operation object
* @param {object} parsedXml the content file in javascript object representation
* @param {object} bindingOperation binding operation to find the element
* @param {object} elementsFromWSDL all the elements of the document
* @param {string} principalPrefix the principal prefix of the document
* @param {string} protocolPrefix the binding information for the binding
* @param {string} inputTag the tag for search of input
* @param {string} headerTag the tag for search of header
* @param {object} tnsNamespace tns namespace object
* @returns {object} the WSDLObject
*/
getElementFromBindingOperation(parsedXml, bindingOperation, elementsFromWSDL, principalPrefix, protocolPrefix,
inputTag, headerTag, tnsNamespace) {
let inputInformation = getNodeByName(bindingOperation, principalPrefix, inputTag),
headerInformation = getNodeByName(inputInformation, protocolPrefix, headerTag),
messageName, elementName,
elementsArray = [];
if (headerInformation) {
if (!Array.isArray(headerInformation)) {
headerInformation = [headerInformation];
}
headerInformation.forEach((header) => {
let foundElement;
messageName = getAttributeByName(header, ATTRIBUTE_MESSAGE);
elementName = this.getMessageElementNameByMessageName(parsedXml, principalPrefix, messageName, tnsNamespace);
if (elementName === EMPTY_ELEMENT_BY_DEFAULT) {
elementsArray.push(createEmptyElement(elementName));
return;
}
elementName = excludeSeparatorFromName(elementName);

if (Array.isArray(elementsFromWSDL)) {
foundElement = elementsFromWSDL.find((element) => {
return element.name === elementName;
});
}

if (foundElement === undefined) {
elementsArray.push(createErrorElement({}, elementName));
}
else {
elementsArray.push(foundElement);
}
});
return elementsArray;
}
return [];
}

/**
* finds the element from the port type operation object
Expand Down
52 changes: 52 additions & 0 deletions lib/WsdlInformationService20.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const
DOCUMENTATION_TAG = 'documentation',
NAME_TAG = 'name',
INPUT_TAG = 'input',
HEADER_TAG = 'header',
OUTPUT_TAG = 'output',
OUTFAULT_TAG = 'outfault',
ADDRESS_TAG = 'address',
Expand Down Expand Up @@ -68,6 +69,7 @@ class WsdlInformationService20 {
constructor() {
this.version = '2.0';
this.InputTagName = INPUT_TAG;
this.HeaderTagName = HEADER_TAG;
this.NameTag = NAME_TAG;
this.OutputTagName = OUTPUT_TAG;
this.FaultTagName = OUTFAULT_TAG;
Expand Down Expand Up @@ -504,6 +506,56 @@ class WsdlInformationService20 {
return this.getElementFromInterfaceOperationInOut(interfaceOperation, elementsFromWSDL, principalPrefix, tag);
}

/**
* finds the element from the port type operation object
* @param {object} parsedXml the content file in javascript object representation
* @param {object} bindingOperation binding operation to find the element
* @param {object} elementsFromWSDL all the elements of the document
* @param {string} principalPrefix the principal prefix of the document
* @param {string} protocolPrefix the binding information for the binding
* @param {string} inputTag the tag for search of input
* @param {string} headerTag the tag for search of header
* @param {object} tnsNamespace tns namespace object
* @returns {object} the WSDLObject
*/
getElementFromBindingOperation(parsedXml, bindingOperation, elementsFromWSDL, principalPrefix, protocolPrefix,
inputTag, headerTag, tnsNamespace) {
let inputInformation = getNodeByName(bindingOperation, principalPrefix, inputTag),
headerInformation = getNodeByName(inputInformation, protocolPrefix, headerTag),
messageName, elementName,
elementsArray = [];
if (headerInformation) {
if (!Array.isArray(headerInformation)) {
headerInformation = [headerInformation];
}
headerInformation.forEach((header) => {
let foundElement;
messageName = getAttributeByName(header, ATTRIBUTE_MESSAGE);
elementName = this.getMessageElementNameByMessageName(parsedXml, principalPrefix, messageName, tnsNamespace);
if (elementName === EMPTY_ELEMENT_BY_DEFAULT) {
elementsArray.push(createEmptyElement(elementName));
return;
}
elementName = excludeSeparatorFromName(elementName);

if (Array.isArray(elementsFromWSDL)) {
foundElement = elementsFromWSDL.find((element) => {
return element.name === elementName;
});
}

if (foundElement === undefined) {
elementsArray.push(createErrorElement({}, elementName));
}
else {
elementsArray.push(foundElement);
}
});
return elementsArray;
}
return [];
}

/**
* finds the element from the interface operation object when is called
* for input or output
Expand Down
10 changes: 10 additions & 0 deletions lib/WsdlParser.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,16 @@ class WsdlParser {
newWsdlObject.tnsNamespace,
portTypeInterfaceName
);
wsdlOperation.header = this.informationService.getElementFromBindingOperation(
parsedXml,
bindingOperation,
elements,
principalPrefix,
bindingTagInfo.protocolPrefix,
this.informationService.InputTagName,
this.informationService.HeaderTagName,
newWsdlObject.tnsNamespace,
);
wsdlOperation.output = this.informationService.getElementFromPortTypeInterfaceOperation(
parsedXml,
portTypeInterfaceOperation,
Expand Down
30 changes: 18 additions & 12 deletions lib/WsdlToPostmanCollectionBodyMapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,18 @@ class WsdlToPostmanCollectionBodyMapper {
* @param {*} elementToCreateBody the root node for the message parameters
* @param {array} securityPolicyArray An array with all security policies
* @param {object} xmlParser the parser class to parse xml to object or vice versa
* @param {array} soapBodyHeaders the headers for the soap body
* @returns {array} An array with all items generated in postman item definition format
*/
getBody(operation, elementToCreateBody, securityPolicyArray, xmlParser) {
getBody(operation, elementToCreateBody, securityPolicyArray, xmlParser, soapBodyHeaders) {
if (operation.protocol === SOAP_PROTOCOL ||
operation.protocol === SOAP12_PROTOCOL) {
return this.createBodyForSOAP(elementToCreateBody, securityPolicyArray, xmlParser, operation.protocol);
return this.createBodyForSOAP(elementToCreateBody, securityPolicyArray, xmlParser,
operation.protocol, soapBodyHeaders);
}
if (operation.protocol === HTTP_PROTOCOL) {
return this.createBodyForHTTP(operation, elementToCreateBody, securityPolicyArray, true, xmlParser);
return this.createBodyForHTTP(operation, elementToCreateBody, securityPolicyArray, true,
xmlParser, soapBodyHeaders);
}
}

Expand All @@ -61,8 +64,7 @@ class WsdlToPostmanCollectionBodyMapper {
getResponseBody(operation, elementToCreateBody, securityPolicyArray, xmlParser) {
if (operation.protocol === SOAP_PROTOCOL ||
operation.protocol === SOAP12_PROTOCOL) {
return this.getSOAPBodyMessage(elementToCreateBody, securityPolicyArray, operation.protocol,
xmlParser);
return this.getSOAPBodyMessage(elementToCreateBody, securityPolicyArray, operation.protocol, xmlParser);
}
if (operation.protocol === HTTP_PROTOCOL) {
return this.createBodyForHTTP(operation, elementToCreateBody, securityPolicyArray, false, xmlParser);
Expand All @@ -77,13 +79,14 @@ class WsdlToPostmanCollectionBodyMapper {
* @param {array} securityPolicyArray An array with all security policies
* @param {object} xmlParser the parser class to parse xml to object or vice versa
* @param {string} protocol the operation protocol
* @param {array} headers headers for soap body
* @returns {array} An array with all items generated in postman item definition format
*/
createBodyForSOAP(elementToCreateBody, securityPolicyArray, xmlParser, protocol) {
createBodyForSOAP(elementToCreateBody, securityPolicyArray, xmlParser, protocol, headers) {
return {
mode: 'raw',
raw: this.getSOAPBodyMessage(elementToCreateBody, securityPolicyArray, protocol,
xmlParser),
xmlParser, headers),
options: {
raw: {
language: XML
Expand All @@ -100,9 +103,10 @@ class WsdlToPostmanCollectionBodyMapper {
* @param {array} securityPolicyArray An array with all security policies
* @param {boolean} isInput if the body message corresponds to an input
* @param {object} xmlParser the parser class to parse xml to object or vice versa
* @param {array} soapBodyHeaders the headers for the soap body
* @returns {array} An array with all items generated in postman item definition format
*/
createBodyForHTTP(operation, elementToCreateBody, securityPolicyArray, isInput, xmlParser) {
createBodyForHTTP(operation, elementToCreateBody, securityPolicyArray, isInput, xmlParser, soapBodyHeaders) {
if (isInput) {
if (operation.method === GET_METHOD) {
return undefined;
Expand All @@ -114,14 +118,15 @@ class WsdlToPostmanCollectionBodyMapper {
urlencoded: helper.convertInputToURLEncoded(elementToCreateBody)
};
}
return this.createBodyForSOAP(elementToCreateBody, securityPolicyArray, xmlParser, SOAP_PROTOCOL);
return this.createBodyForSOAP(elementToCreateBody, securityPolicyArray, xmlParser,
SOAP_PROTOCOL, soapBodyHeaders);
}
else if (!isInput) {
if (operation.mimeContentOutput && operation.mimeContentOutput.mimeType === MIME_TYPE_XML) {
return this.xMLMessageHelper.convertInputToMessage(elementToCreateBody, xmlParser);
}
return this.getSOAPBodyMessage(elementToCreateBody, securityPolicyArray, SOAP_PROTOCOL,
xmlParser);
xmlParser, soapBodyHeaders);
}
}

Expand All @@ -134,12 +139,13 @@ class WsdlToPostmanCollectionBodyMapper {
* @param {array} securityPolicyArray An array with all security policies
* @param {string} protocol the protocol to implement the message default 'soap'
* @param {object} xmlParser the parser class to parse xml to object or vice versa
* @param {array} headers the headers for soap body
* @returns {string} the message xml with the structure determined in the
* elements and the default values examples
*/
getSOAPBodyMessage(nodeElement, securityPolicyArray, protocol, xmlParser) {
getSOAPBodyMessage(nodeElement, securityPolicyArray, protocol, xmlParser, headers) {
return this.sOAPMessageHelper.convertInputToMessage(nodeElement, securityPolicyArray, protocol,
xmlParser);
xmlParser, headers);
}

}
Expand Down
2 changes: 1 addition & 1 deletion lib/WsdlToPostmanCollectionMapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ class WsdlToPostmanCollectionMapper {
createItemsFromOperations(operations, urlVariablesData, securityPolicyArray, xmlParser) {
let items = operations.map((operation) => {
let requestBody = this.wsdlToPostmanCollectionBodyMapper
.getBody(operation, operation.input[0], securityPolicyArray, xmlParser),
.getBody(operation, operation.input[0], securityPolicyArray, xmlParser, operation.header),
postmanItem = {
name: operation.name,
request: {
Expand Down
20 changes: 18 additions & 2 deletions lib/utils/SOAPMessageHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,13 @@ class SOAPMessageHelper {
* @param {Element} headerInfo node taken from parsedXml
* @param {string} protocol Protocol being used
* @param {Object} xmlParser the xml parser for the process
* @param {array} headers the headers for the soap body
* @returns {string} the rootParametersElement in xml string
*/
convertInputToMessage(rootParametersElement, headerInfo, protocol, xmlParser) {
convertInputToMessage(rootParametersElement, headerInfo, protocol, xmlParser, headers) {
let envelopeAndProtocol = protocol + envelopeName,
jObj = {},
headerElement = {},
bodyAndProtocol = protocol + bodyName,
resultMessage = '',
cacheKey = this.getHashedKey(rootParametersElement, headerInfo, protocol, this.getCompundKey,
Expand All @@ -99,7 +101,21 @@ class SOAPMessageHelper {
}
const soapParametersUtils = new SOAPBody(xmlParser),
soapHeaderUtils = new SOAPHeader(xmlParser);
jObj[envelopeAndProtocol][headerAndProtocol] = soapHeaderUtils.create(headerInfo, protocol);

if (headers && Array.isArray(headers) && headers.length > 0) {
headers.forEach((header) => {
headerElement = { ...headerElement, ...soapParametersUtils.create(header, protocol) };
});
headerElement = { ...headerElement,
...soapHeaderUtils.create(headerInfo, protocol) };

if (Object.keys(headerElement).length > 0) {
jObj[envelopeAndProtocol][headerAndProtocol] = headerElement;
}
}
else {
jObj[envelopeAndProtocol][headerAndProtocol] = soapHeaderUtils.create(headerInfo, protocol);
}
jObj[envelopeAndProtocol][bodyAndProtocol] = soapParametersUtils.create(rootParametersElement,
protocol);

Expand Down
5 changes: 5 additions & 0 deletions test/data/validWSDLs11/elementFormDefaultQualified.wsdl
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,11 @@
<xsd:element name="Xpath" type="xsd:string" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Workday_Common_HeaderType">
<xsd:sequence>
<xsd:element name="Include_Reference_Descriptors_In_Response" type="xsd:boolean" minOccurs="0" maxOccurs="1"/>
aman-v-singh marked this conversation as resolved.
Show resolved Hide resolved
</xsd:sequence>
</xsd:complexType>
<xsd:attribute name="version" type="xsd:string" wd:fixed="v39.0" />
</xsd:schema>
</wsdl:types>
Expand Down
Loading
Loading