Enrich soap message with ESQL - soap

I am creating a simple flow that receives a message via SOAP and in IIB I treat the message with ESQL.
This is my SOAP message:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:com="http://ComponentesTI">
<soapenv:Header/>
<soapenv:Body>
<com:PushMessageRequest>
<Message>
<SerializedContent>?</SerializedContent>
<HTTPAddress>?</HTTPAddress>
</Message>
<Identification>?</Identification>
</com:PushMessageRequest>
</soapenv:Body>
</soapenv:Envelope>
I need to replicate this message just by changing the Identification field using ESQL (using a GUID)
Something like that:
CREATE LASTCHILD OF OutputRoot DOMAIN 'XMLNSC';
DECLARE statement REFERENCE TO OutputRoot.XMLNSC;
DECLARE statement2 REFERENCE TO InputRoot.XMLNSC;
SET statement = statement2;
SET statement.PushMessageRequest.Identification = UUIDASCHAR;

You forgot to use XML namespace in the ESQL syntax.
CREATE LASTCHILD OF OutputRoot DOMAIN 'XMLNSC';
DECLARE statement REFERENCE TO OutputRoot.XMLNSC;
DECLARE statement2 REFERENCE TO InputRoot.XMLNSC;
SET statement = statement2;
DECLARE com NAMESPACE 'http://ComponentesTI';
SET statement.com:PushMessageRequest.Identification = UUIDASCHAR;

The code fragments below take into account the SOAP Envelope.
Copy everything including the Properties folder and any other Header folders and then change the Identification field.
SET OutputRoot = InputRoot;
SET OutputRoot.XMLNSC.*:Envelope.*:Body.*:PushMessageRequest.Message.Identification = UUIDASCHAR;
Create a new XMLNSC aggregate with other code handling the Properties folder and other headers as required.
CREATE LASTCHILD OF OutputRoot DOMAIN 'XMLNSC';
SET OutputRoot.XMLNSC.*:Envelope.*:Body.*:PushMessageRequest.Message.Identification = UUIDASCHAR;
Also depending on whether you are using an HTTPInput vs a SOAPInput Node the top level aggregate may be SOAP rather than XMLNSC.
Lastly as we aren't changing any of the namespaces and are overwriting the value in Identification I used the syntax *: for the namespace so I didn't have to declare the namespace variables for soapenv and com

Related

How to set SOAPMessageContext Variables in Postman

I am trying to use Postman to test an old outdated SOAP Service. The service is expecting some identities to be placed in a Handler Chain to obtain from the request. In the request it obtains the values in the following manner (with some exclusions):
import javax.annotation.Resource;
#Resource
private WebServiceContext webServiceContext;
public MyResponse methodEvent(...) {
...
String var1 = (String) context.getMessageContext().get("VAR1");
...
}
My question is when trying to use Postman how can I set this value in the request. It is not part of the normal headers or other standard entries.
It is possible before SOAP API call.
You can using the response of output to assign result variable
It can use other call output
From three different inputs
#1 Pre-request Script
#2 Global variable
#3 From other request output - I think you looking for this solution.
Demo - I will show ADD operation in Calculator SOAP
SOAP service URL
http://www.dneonline.com/calculator.asmx
Using variables input_a, input_b for adding
#1 Pre-request Script
value defined at Pre-request Script
postman.setEnvironmentVariable("input_a", 3);
postman.setEnvironmentVariable("input_b", 4);
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<Add xmlns="http://tempuri.org/">
<intA>{{input_a}}</intA>
<intB>{{input_b}}</intB>
</Add>
</soap:Body>
</soap:Envelope>
Result
#2 Global variable
Result
#3 From other request output - XML parsing and assign variable
You can using this output variable for other SOAP call's input
var xmlTree = xml2Json(responseBody);
var text = xmlTree["soap:Envelope"]["soap:Body"]["AddResponse"]["AddResult"];
console.log(text)
postman.setEnvironmentVariable("output_result", Number(text));
console.log(postman.getEnvironmentVariable("output_result"));
Print the parsing variable

REST request in SOAP UI

I am trying to make a REST POST request in SoapUI.. The XML contract for the same is
<Login>
<Email>admin</Email>
<Password>123456</Password>
</Login>
I have passed the values as follows in the REST request in SoapUI to the URL http://localhost:8080/SalesPropeller/rest/api/restLogin
Name Value Style level
Email admin Query Resource
Password 123456 Query Resource
How do I pass the parameters in SoapUI?
Should the root tag name be included?If yes, How?
It is based on how your backend expects the payload.
From XML Contract, Your request payload should be like this
<Login>
<Email>admin</Email>
<Password>123456</Password>
</Login>
If you want to add properties, to send variables as field values
<Login>
<Email>${propertyName}</Email>
<Password>${propertyName}</Password>
</Login>
For creating properties, refer http://www.soapui.org/functional-testing/properties/working-with-properties.html

AXIS SOAP wsdlPortType

What do these parameters do and what are they used for?
<service name="...">
<parameter name="wsdlPortType" value="..."/>
</service>
Also, if anyone can explain the parameters wsdlServicePort, wsdlTargetNamespace, and wsdlServiceElement, that would be appreciated.
Axis 1.4 User's Guide:
When you deploy a service in Axis, users may then access your
service's URL with a standard web browser and by appending "?WSDL" to
the end of the URL, they will obtain an automatically-generated WSDL
document which describes your service.
Experimental results suggest that Axis is able to use a combination of the .wsdd deployment descriptor file and compiled Java .class files to generate the corresponding .wsdl for a given service. It's interesting to note that, for example, if you have a public method with a Generics return type such as Map, your generated .wsdl file will not contain the return type - it will contain "xsd:anyType" instead. I believe this is due to type erasure on the compiled .class file.
Anyway, the service options in the Axis .wsdd file (the parameters I referenced in my question such as wsdlPortType, wsdlServicePort, and wsdlTargetNamespace) are related to the .wsdl specifications. This can be inferred from the names themselves since they all contain 'wsdl' in them, but I wanted an explanation of what these parameters mean and I was unable to find relevant Axis documentation. Here are my findings:
wsdlPortType (portType): basically like a Java interface. Contains one "operation" element for each method name. Each "operation" contains "input" and "output" elements that are basically your input parameters and return parameter of the Java method.
wsdlServicePort (wsdl:binding) Associated with the portType. I think of it as a description of how to transmit the parameters for the portType. The spec has this to say:
A binding description component provides a framework for indicating
binding details for a portType description component. Binding details
SHOULD be used to indicate how messages MUST be formatted when they
are sent to or from the service. They SHOULD also be used to indicate
the transport protocol to be used to send the messages. A given
binding description component MUST NOT indicate more than one
protocol.
wsdl:service: Has a reference in it to the wsdl port binding (the implementation of the portType).
target namespace: Pretty much what I thought it was (same as a namespace anywhere else). It applies to all of the wsdl:definitions components, so anything in the wsdl file basically (wsdl:portType, wsdl:service, etc). There are a couple other rules that you can find in the spec though.
Problem:
When using Service?wsdl, the generated wsdl may not have
the same targetNamespace, portType, service element name, or
service port name as the original wsdl. This problem has
been reported by users and is a TCK issue.
Solution:
Four optional parameters are added to the deploy.wsdd and
queried by the JavaProvider (wsdlTargetNamespace, wsdlServiceElement,
wsdlServicePort and wsdlPortType).
Here is an example deploy.wsdd with the new parameters.
<!-- Services from AddressBookService WSDL service -->
<service name="AddressBook" provider="java:RPC">
<parameter name="wsdlTargetNamespace" value="urn:AddressFetcher2"/>
<parameter name="wsdlServiceElement" value="AddressBookService"/>
<parameter name="wsdlServicePort" value="AddressBook"/>
<parameter name="className" value="samples.addr.AddressBookSOAPBindingSkeleton"/>
<parameter name="wsdlPortType" value="AddressBook"/>
<parameter name="allowedMethods" value="*"/>
<parameter name="scope" value="Session"/>
Source: http://mail-archives.apache.org/mod_mbox/axis-java-dev/200206.mbox/%3C20020621143740.41268.qmail#icarus.apache.org%3E

SOAPUI Extract data from SOAP Response and use in REST request

I have been looking at the answer to this question:
Pulling details from response to new request SoapUI
which is similar to what I am looking for but I can't get it to work.
I have a small SOAPUI testsuite and I need to extract a value from the response of a SOAP request and then use this value in a subsequent REST request.
The response to my SOAP request is:
<ns0:session xmlns:ns0="http://www.someurl.com/la/la/v1_0">
<token>AQIC5wM2xAAIwMg==#</token>
</ns0:session>
so I need the token to use in my REST request. I know it involves using Property Transfer and some XPath / XQuery but I just can't get it right. At the moment my property transfer window points to Source: SOAP test Property: Response and has data(/session/token/text()) in the text box. In target it has Target: REST testcase Property: newProp and I have Use XQuery checked.
Any help greatly appreciated.
Thanks,
Adrian
I think you just need to declare the namespace ns0 and use it in the XPath. Also, uncheck the XQuery, it is only used when you are using XQuery, not XPath.
Replace your expression with this:
declare namespace ns0='http://www.someurl.com/la/la/v1_0';
/ns0:session/token/text()

Adding SOAP implicit headers to WSDL

My question is similar to this. How To Pass Soap Header When WSDL Doesn't Define It? But is different.
For a web service I use, all methods need authentication which is sent in cleartext inside a SOAP header. However, my WSDL doesn't include any soap header information. I have a custom platform tool which I must use to generate code from the WSDL. Since the header info is not available, am unable to use the generated class directly - I do not want to manually modify the code to accommodate the header.
I tried specifying the SOAP header in the WSDL but I failed to get the correct namespaces. The WSDL is here https://stage.totalcheck.sensis.com.au/service/webservice?wsdl and the SOAP header is as follows:
<soapenv:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>username</wsse:Username>
<wsse:Password>password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
Can someone help me? Thanks!
From a conceptual point of view, WSDL is not supposed to define headers. WSDL is only for defining the functional aspects of a service, like operations, messages, binding and endpoints. Messages and bindings define how the payload of messages should be encoded and formatted.
The headers of SOAP messages however do not belong to the payload. They are typically used for configuring non-functional properties of a SOAP processor. Security is such a non-functional property. The functional aspect of the payload is not affected. It is only assured that the communication is secured and the WS tool stack, not the service implementation, should take care of that.
So the missing piece is now a standard that allows for attaching some non-functional requirements to WSDL services, so that code generators can automatically derive which headers need to be sent and/or understand in order to fulfill the non-functional property as desired -- without having to manually deal with header fields. This standard exists and is called WS-Policy. A policy contains typically a set of alternatives that expose a set of requirements that both, provider and consumer should be able to fulfill. When two services are supposed to interact with each other, both policies are taken and a so called "effective policy" is calculated. It defines the common non-functional requirements. Using this information, provider and consumer can configure themselves to add required headers, like the WS-Security headers. WS-SecurityPolicy also defines a set of policies that can be used. WS-PolicyAttachment defines how such policies can be attached to a WSDL.
There are code generators that can deal with WS-Policies, e.g. Metro or Axis2
You can add soap header information to method calls by decorating the methods in the proxy class generated from the wsdl with the SoapHeader attribute.
For example wsdl.exe will generate client proxy class Reference.cs for the web service reference when you "Add Web Reference". In the link mentioned above https://stage.totalcheck.sensis.com.au/service/webservice?wsdl there is a message suggestAddress which will translate to a method in the generated reference.cs client proxy code file when you add a web reference from visual studio. By default when this method is called there will be no Header in the soap envelope. To add a SoapHeader to the envelope for this request add a [SoapHeader("Security")] attribute to the top of the SuggestAddress method in the Reference.cs generated class, where "Security" is a class that inherits from SoapHeader base class.
Example for the above required Security SoapHeader you would create the following classes,
public partial class Security : SoapHeader
{
public UserNameToken UserNameToken { get; set; }
}
public partial class UserNameToken
{
public string UserName { get; set; }
public string Password { get; set; }
}
Then you would decorate the SuggestAddress method in the reference.cs like followed,
[SoapHeader("Security")]
public suggestAddressesResult suggestAddresses([System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)] addressSearch search) {
object[] results = this.Invoke("suggestAddresses", new object[] {search});
return ((suggestAddressesResult)(results[0]));
}
This will ensure that every envelope created when method suggestAddress is invoked contains a security header that looks like the one mentioned above,
<soapenv:Header>
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>username</wsse:Username>
<wsse:Password>password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
Key for me in using this question to help myself was recognizing (as some pointed out) that the headers in question are those of WS-Security standard.
If your proxy generating tool is "custom" it seems logical that you might have a switch to automatically add the headers for WS-Security. However, if you're using WSDL.exe ("Add Web Reference" in Visual Studio), consider svcutil.exe instead ("Add Service Reference").
If you use a WCF proxy, you can override the given config and allow WCF to add the headers for you:
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
From there you can specify the password:
RemoteSvcProxy.TheirClient client = new RemoteSvcProxy.TheirClient();
client.ClientCredentials.UserName.UserName = "uname";
client.ClientCredentials.UserName.Password = "pwd";
I don't know what your custom tool is, but perhaps the framework it's based on also has similar configuration options.