Do not input private or sensitive data. View Qlik Privacy & Cookie Policy.
Skip to main content

Announcements
Write Table now available in Qlik Cloud Analytics: Read Blog
cancel
Showing results for 
Search instead for 
Did you mean: 
Anonymous
Not applicable

tSOAP - access the response header

Hello,

i have been searching around now for quite a time, I want to communicate with a SOAP Webservice where the process is the following:

 

  1. connect with the Webservice via Login Credentials sent in the body part
  2. receive a Cookie from the header of the response to the login message
  3. use the received cookie for further requests on the webservice

This is a quite common scenario.

 

Component options which i have tested:

- tSOAP component - no chance to get the HTTP header information out of that

- tWebservice component - same.

- tHttpRequest - no chance to get the HTTP header out of the response, only the body part - WTF is this component else for instead of raw HTTP requests?!?

- tESBConsumer component with hacks to get to the HTTP header - does somehow not work for me (see https://community.talend.com/t5/Design-and-Development/resolved-SOAP-header-in-tJavaRow/m-p/78503#M3...)

 

Can someone suggest a solution? Reading out a cookie from a HTTP response Header is not that uncommon and i think Talend should support this kind of stuff out of the box, tell me when i'm not right. My alternative currently is to just use Java Code for building a component which should already exist?!?

Labels (4)
25 Replies
Anonymous
Not applicable
Author

can i somehow just use a tJavaRow or something like that to just remove the string by a simple regex? My brain hurts when thinking of this overengineered solution for just making components work for standard needs. Dear Talend original component coders, I am not pleased by your solution of handling SOAP! 0683p000009MA9p.png The funny thing is, that i'm replacing a Pentaho ETL job with a Talend job here - and in Pentaho the solution was already a nearly complete rebuild of a SOAP communication componente for the request.
Anonymous
Not applicable
Author

OK, here is another experiment to show you what I mean. Where you had a tLogRow, replace it with a tFileOutputXML (leaving all of the defaults). Run the job and open the output file. You will notice your XML wrapped in other elements (your column name and one called row with an outer element of root). At the top you will see the XML header. This is what will happen with the tESBConsumer. You do not need to worry about the header, Your error is elsewhere. IF you tested the XML with the header using another tool, yes you will see an error. Talend will not send the body with the XML header.

Anonymous
Not applicable
Author

Hello rhall_2_0,

 

i tried with a tFileOutputXML with all defaults and this is my resulting file:

0683p000009M0FK.png

 

if i just use whats in the payload for the SOAP body part in an external tool like SOAP UI, it gets accepted (see below). I simplyfied it now for having only the payload, as i do not need to send any information via the header. As you can see on the last part of the screens here, the correct action is selected.

0683p000009M0He.png

When combining this with just the tESBConsumer part as defined in my other messages here, i get the following errors:

0683p000009M0F0.png

Do i need to send SOAP headers additionally somehow? My example request has an empty soapenv:header part but is using the urn:xxxxxx_xxxx#login action, the same which I selected in the tESBConsumer Component as seen above. 

 

Anonymous
Not applicable
Author

Your example that errors in SOAP UI is NOT what Talend is doing. The XML header is ignored. If it were not, absolutely no jobs that use the tESBCOnsumer would work. I have several working here.

 

The error you are getting from Talend is telling you there is an encoding violation with your data. SOAP UI is far more forgiving than practically any other tool. For us to be able to help we will need to see the WSDL and the data you were sending.

 

 

Anonymous
Not applicable
Author

This is parts of the WSDL where i replaced the service provider name with "Provider" and the exact WSDL service with "serviceReport". I excluded all the other topics from the WSDL here...

0683p000009LzdB.png

Anonymous
Not applicable
Author

I can't see what you are supplying, but my suspicion is that the Network element may be causing this issue. The WSDL has it requiring an int, but in your "Expected" example from earlier you have it set to MYNETWORK. Are you passing a String or an int? 

 

Unfortunately web services are notoriously difficult to debug since you seldom have control over both ends (client and server). 

Anonymous
Not applicable
Author

I am passing an integer. The contents of the body when I copy it from the log or from the experimental xml output file are accepted by the API and return a successful login result, when I do the request via SOAP UI. Same goes for just submitting the XML file (which I read in with the tFileInputXML component) directly via curl. My assumption is that the tESBConsumer component somehow messes up the SOAP envelope structure. I will use Wireshark to see what exactly Talend is sending out to the server, I already thought about building a micro nodejs server to replace the api endpoint and show me the raw request...
Anonymous
Not applicable
Author

There is something else to try. You should really build the XML with Talend. If you follow these steps, you can import the request schema from your WSDL and use it with a tXMLMap to build it before passing it to the tESBConsumer.

 

1) Find the Services branch in your project's tree structure, right click on it and select "Create Service". Give it a name, and click Next. Then select "Import WSDL". Put your WSDL url in the box that appears (remember it must end with ?WSDL). Click Finish.

2) Now go to your Metadata, then expand File XML. You should see a folder within there which is related to your SOAP service. Inside, it will hold both the Request and Response schemas for your service. I assume you have many actions, so there may be a few of these.

3) Now add tFixedFlowInput component to your job. Make it the start component. Add appropriate typed columns to hold the data you need to send.

4) Now add a tXMLMap component and join it to the tFixedFlowInput. Open the tXMLMap and add an output table. In that, add a "payload" column of type Document. Right click on the payload column and select "Import from repository". Now find your Request schema. When you have selected it, your Request schema will appear. 

5) Connect up your input columns to their respective output elements.

6) Connect your tXMLMap to a tLogRow and run the job. Take a look at the format of the XML. You can also test this in SOAP UI (remember to remove the XML header for SOAP UI....Talend does this for you). If it works, then remove the tLogRow and connect your configured tESBConsumer.

 

If you follow this process, it should eliminate any errors that may have crept in by dicing and splicing XML. 

Anonymous
Not applicable
Author

Did this work for you?

Anonymous
Not applicable
Author

Hello rhall_2_0,

I now managed to get the tESBConsumer component working. Somehow my Talend Installation won't let me automatically produce the XML Schemas from the WSDL file when I create a Service in the Context and import the WSDL file there. I created the XML Schemas on my own and then changed it in the tXMLMap component again. Here's what i've done in screenshots:

 

0683p000009Lzxq.pngthe flow0683p000009M0J1.pngthe XMLMap component to generate the SOAP Body Content0683p000009M0J6.pngThis is my advanced settings where I put SOAP settings in the Header0683p000009M01m.pngExtracting the Login Response (true/false)0683p000009M03M.pngMapping the Response (maybe i should rewrite the error condition just as a negation of the true response)

 

Now that I got the response, I am stuck at extracting the response's header.

I added a tJava Component with the code below and i'm just getting a nullPointerException.

 

Advanced Settings

import java.util.List;
import java.util.Map;
import java.util.Iterator;

Code

System.out.println("Get Cookie from Header");
try {
	java.util.Map<String,java.util.List<String>> headers =((java.util.Map<String,java.util.List<String>>)globalMap.get("tESBConsumer_3_HEADERS"));

java.util.Iterator<String> it = headers.keySet().iterator();
	while(it.hasNext()){
		System.out.println(it.next());
		// todo: cookie processing
		// check if line has the cookie in it
		// if yes, write the cookie to a context variable
	} 
} catch (Exception nullPointerException) {
	// TODO: handle exception
	System.out.println("nullPointerException");
}

 

The tESBConsumer Headers should be a Map with a String and a String List, am I doing anything wrong, e.g. the Java Code is executed before the tESBConsumer has received the Headers and the value is avaiable in the globalMap?

 

0683p000009M06Z.png