Losing attachments in Axis2 response - java

I'm trying to send an attachment to client from Axis2 web service. The problem is that the message context, which client receives from the service, does not contain any attachments, though the last one seems to add it.
Here is the brief code of both sides.
Service:
MessageContext inMC = MessageContext.getCurrentMessageContext();
OperationContext operationContext = inMC.getOperationContext();
MessageContext outMC = operationContext.getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
DataHandler handler = new DataHandler (new FileDataSource("C://goods.xml"));
String attachID = outMC.addAttachment(handler);
OMElement idElem = factory.createOMElement("doc", ns);
idElem.addAttribute("href", "cid:" + attachID, ns);
Client (trying to receive attachment):
MessageContext mcResponse = operationClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
SOAPBody body = mcResponse.getEnvelope().getBody();
OMElement attachElem = body.getFirstChildWithName (new QName("doc"));
String attachID = attachElem.getAttributeValue (new QName("href"));
attachID = attachID.replaceFirst("cid:", "");
DataHandler dataHandler = mcResponse.getAttachment(attachID);
getAttachment() method returns null. In case of debugging the client application, IDE shows, that attachment map in input message context does not contain any elements (size=0). The OMElement object (idElem), which contains attachment id, is received and read by client normally (debug showed cid). The parameters enableSwA, cacheAttachments, attachmentDIR, sizeThreshold are set both in services.xml and programming part of client. What is wrong with the message context?
Thanks a lot for any suggestions.
Upd: TCPmon showed the following content.
Request to service:
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><getXMLFile xmlns="http://axis2.apache.org"><filename>goods.xml</filename></getXMLFile></soapenv:Body></soapenv:Envelope>
I guess it's ok :)
Response from service:
109
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><doc href="cid:d06f3b36afdfcbd2e135ecfbcad05ee602661262b059ed38#apache.org"></doc></soapenv:Body></soapenv:Envelope>
0
I apologize for a bit simple questions, but where the attachment should be reflected? I guess, if the service send an attachment, the SOAP message contains binary data, isn't it?
I checked also for putting the attachment into message context on service side - it's OK, I can get it there back from context after adding.

you can use tcpmon[1] to trace the http message and isolate the problem.
Anyway the better method for handling attachments is to use MTOM. Which can be used with data binding frameworks like ADB[2], or with POJO as well.
thanks,
Amila.
[1] http://ws.apache.org/commons/tcpmon/
[2] http://amilachinthaka.blogspot.com/2009/01/using-mtom-with-axis2.html

The problem was solved. The trouble was on the service side. TCPmon showed there was no attachments in responce message. However, the same example service works fine. After checking and comparing every operation on my service, it came out that programming part is not the reason either. The only one was left - service settings. So, the reason is that settings fields in service.xml file on the service, which require boolean type, does not allow any additional symbols. My mistake:
Incorrect:
<parameter name="enableSwA">
true
</parameter>
Correct:
<parameter name="enableSwA">true</parameter>

Related

How to display SOAP Request Message on client side application before request is sent or if request is not sent?

I have to build a UI that consumes and needs to display the xml request and responses to a SOAP Web Service.
(This is the first time I am working with SOAP and also my first stack question).
All the questions I've seen only answer half of what I'm asking.
Is there a way to display the request xml even if the soap request is not sent?
This code snippet is me binding the ServicePort object (generated by wsimport), to MyHandler, which implements SOAPHandler <SOAPMessageContext>
eftServicePort = new EFTService(new URL(uri)).getEFTPort();
handler = new MyHandler();
Binding binding = ((BindingProvider) eftServicePort).getBinding();
List<Handler> handlerList = binding.getHandlerChain();
handlerList.add(handler);
binding.setHandlerChain(handlerList);
This works fine when the URI is correct. I can display both the request and response xml on screen.
If the uri is incorrect/invalid (at the first line) an exception is thrown and the handler object is not created or bound to the ServicePort object.

adding raw text to a SOAP header

In Java, I need to add a SOAP header containing authentication data for a client-side SOAP request to a 3rd party web service that I have no control over. I have set up a SOAPHandler, and am monitoring the actual code sent to the server-side to see what is going on. The authentication is not working.
What I precisely need is:
<soap12:Header>
<AuthenticationHeader xmlns="http://abc.xyz.com/">
<UserName>uname</UserName>
<Password>pwd</Password>
</AuthenticationHeader>
</soap12:Header>
I can create the AuthenticationHeader element and add it with the SOAPHeader.addHeaderElement method without issue, but I can't get the username and password content added properly. What I can get from using the various commands to set the text for a SOAPElement (setValue, setTextContent, addTextNode), and then using SOAPHeaderElement.addChildElement is
<soap12:Header>
<AuthenticationHeader xmlns="http://abc.xyz.com/">
<UserName xmlns="">uname</UserName>
<Password xmlns="">pwd</Password>
</AuthenticationHeader>
</soap12:Header>
The server side can't cope with the extra xmlns="" that all the commands I have tried seem to add to the UserName and Password tag names.
If I try to construct a string and add that text directly to the AutheticationHeader element, the < and > characters are escaped. I've also tried CDATA tags...that prevents escaping of the < and > characters, but the server still doesn't like it.
I found a solution constructing a Document to hold the raw text (which prevents escaping the characters), and then adding that, but unfortunately, it seems that Document can only be added to the SOAP body, not the SOAP header.
Does anyone have any suggestions how to overcome this? The server people are programming in .NET, not Java, so they aren't able to help.
I am getting the proper response back from the server, with all off the correct SOAP output tags, but the error message contained in the tag is "Can't Authenticate".
Thanks!
Following code will generate the correct Authentication Header that you would like to generate.
SOAPHeader header = request.getSOAPHeader();
Document doc = header.getOwnerDocument();
Element el1 = doc.createElementNS("http://abc.xyz.com/","UserName");
el1.setTextContent("MyName");
Element el2 = doc.createElementNS("http://abc.xyz.com/","Password");
el2.setTextContent("pass******");
Element el0 = doc.createElementNS("http://abc.xyz.com/", "AuthenticationHeader");
el0.appendChild(el1);
el0.appendChild(el2);
header.appendChild(el0);

How to set additional authentication properties in apache camel DSL or inside the camel Processor?

Here I am trying to convert Json data to CSV format and finally send this file to Ofbiz server api but the api endpoint require some authentication content when I send parameter in URL I got the output below.
{"_ERROR_MESSAGE_":"Error calling event: org.apache.ofbiz.webapp.event.EventHandlerException: Found URL parameter [configId] passed to secure (https) request-map with uri [uploadAndImportFileFromCSVFile] with an event that calls service [uploadAndImportFile]; this is not allowed for security reasons! The data should be encrypted by making it part of the request body (a form field) instead of the request URL. Moreover it would be kind if you could create a Jira sub-task of https://issues.apache.org/jira/browse/OFBIZ-2330 (check before if a sub-task for this error does not exist). If you are not sure how to create a Jira issue please have a look before at https://cwiki.apache.org/confluence/display/OFBIZ/OFBiz+Contributors+Best+Practices Thank you in advance for your help.","sessionId":"someId.jvm1","removePathAlias":false,"loggedIn":true,"USERNAME":"__","_LOGIN_PASSED_":"TRUE","webSiteId":"API"}
After that I used MultipartBuilder to send request below.
exchange.getIn().setHeader("bearer",token);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
File file =new File("//home/r2/Desktop/ofBizFile/orderFile.csv");
builder.addPart("configId",new StringBody("CON_ID"));
builder.addPart("fileTypeEnumId",new StringBody("CSV_FILE"));
builder.addPart("_uploadedFile_contentType",new StringBody("text/csv"));
builder.addPart("uploadedFile",new FileBody(file));
exchange.getIn().setBody(builder.build());
I also tried something like this.
exchange.setProperty(Exchange.CHARSET_NAME, "ISO-8859-1");
exchange.getIn().setHeader(Exchange.HTTP_QUERY,"USERNAME=abc&PASSWORD=bc69");
exchange.getIn().setBody("configId=CON_ID&fileTypeEnumId=CSV_FILE");
Here is my camel route
//Route 1
from("couchdb:http://localhost:5984/order")
.process(new JsonToCsvProcessor())
//Storing file into local directory
.to("file:/home/r2/Desktop/ofBizFile?fileExist=append&fileName=order-${date:now:yyyyMMdd}.csv");
.to("direct:jsonToCsv");
//Route 2
from("direct:jsonToCsv")
.setHeader(Exchange.HTTP_QUERY,constant("USERNAME=__&PASSWORD=__"))
//For get token
.to("https4://SomeAddress.com/centerAPI/getAuthenticationToken")
//Get the token and set required parameter for route 3
.process(new ProcessorGetToken())
.to("direct:hold");
//Route 3
from("direct:hold")
.setHeader(Exchange.HTTP_QUERY,constant("USERNAME=__&PASSWORD=__"))
.to("https4://SomeAddress.com/centerAPI/uploadAndImportFileFromCSVFile?throwExceptionOnFailure=false")
//How I know the file is submited successfuly ?
.to("stream:out").end();
So the problem is how I can send data inside the body in Route2 ProcessorGetToken for next Route3 ?
I'll give a shot into the dark here. Reading your error message:
The data should be encrypted by making it part of the request body (a form field) instead of the request URL
Don't you have a documentation about this integration? I think you need more clarification about this process and what's need to encrypt your data before sending it.
Also, try to set the Exchange.HTTP_METHOD to POST into your route, like this:
exchange.setProperty(Exchange.CHARSET_NAME, "ISO-8859-1");
exchange.getIn().setHeader(Exchange.HTTP_METHOD, "POST");
exchange.getIn().setHeader(Exchange.HTTP_QUERY,"USERNAME=abc&PASSWORD=bc69");
exchange.getIn().setBody("configId=CON_ID&fileTypeEnumId=CSV_FILE");
Take a look into this unit test to see more examples sending data over HTTP. There's also many other tests there.

CXF TransformOutInterceptor removing SOAP attachments when used

I have a SOAP client and I need to set the default namespace - which I am doing with a TransformOutInterceptor as such:
Map<String, String> outTransformMap = Collections.singletonMap("Test", "Test");
org.apache.cxf.interceptor.transform.TransformOutInterceptor transformOutInterceptor = new org.apache.cxf.interceptor.transform.TransformOutInterceptor();
transformOutInterceptor.setDefaultNamespace("http://test");
transformOutInterceptor.setOutTransformElements(outTransformMap);
ClientProxy.getClient(client).getEndpoint().getOutInterceptors().add(transformOutInterceptor);
This is working fine in terms of changing the default namespace, and the SOAP message is being successfully received and parsed by the server, however, by running the transformation it is removing all the SOAP attachments and changing the Content Type of the message from mime to text/xml.
Can anyone help? Is this a bug or am I missing something? I've tried changing the phases at which the interceptor is run, but with to avail.
Many thanks
Matt

Outbound SOAP Handler to edit full SOAPMessage

Is there a way to retrieve the full SOAP message to handle it (envelope and all) when using the javax.xml.soap.SOAPMessage class?
I am using JMX-WS and want to edit the outbound SOAP Message from the server, in order to append two characters to the message AFTER the end closing tag of the envelope, as the client legacy code is expecting it. So ideally I would like to be able to edit the full message as a String, is this possible?
You can do this with cxf :
http://www.mastertheboss.com/web-interfaces/337-apache-cxf-interceptors.html
Take a look at the LogInterceptor example

Categories

Resources