I have an issue with using Camel CXF in PAYLOAD mode. I am sending a SOAP request with body having no namespace prefix.
<soap:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://www.mycompnay.com/test/" xmlns:ns1="http://www.mycompany.com/test/1/">
<soap:Body>
<request>
<ns1:identifier>TEST</ns1:identifier>
</request>
</soap:Body>
</soap:Envelope>
And I am trying to get the cxf body element as cxfPayload.getBody().get(0) which gives me a List of elements.
Now whenever I use a namespace without prefix, the element has a attribute "xmlns:xmlns". And I noticed that this is happening in two places.
DefaultCxfBiding.addNamespace(Element, Map)
CxfPayload.addNamespace(Element, Map)
And in both the places, "xmlns:" is simply prefixed to nsMap.get(key) without checking if the value is xmlns.
This is causing issues during Schema validation and also if the same CXFPayload is sent to another service (Proxy service patterns), it is causing the Out interceptors to fail as "xmlns:xmlns" is not valid namespace attribute.
Appreciate the help as I am not sure if I am missing something here.
It's bug of camel-cxf, I just created a JIRA for it.
Related
I have a REST service wich uses hypermedias with siren content.
To be useable, the client have to send a Accept header with this value :
application/vnd.siren+json
But when i virtualize this service via Centrasite to the Mediator package, requests are rejected.
When i use an accept with only application/json requests are accepted but the content is without hypermedias links, so it is not useable.
I have changed the content-types.xml file in resources of package Mediator like that :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<content-types xmlns="http://contentTypes.mediator.softwareag">
<!-- Please enter the custom content-types
<content-type type="xml">
<name></name>
</content-type>
-->
<content-type type="json">
<name>application/vnd.siren+json</name>
</content-type>
</content-types>
With that, requests with siren are now accepted, but without hypermedias content (as with application/json)
How can i force Mediator to accept this accept header and tranfer it to the endpoint without changing it ?
I use a webMethods Integration Server 9.7 with IS_9.7_Core_Fix19 and a Mediator 9.7.0.0017-0490
Update :
After viewing endpoint logs, it seems that the header and the response are correct, but the response is truncated by mediator.
All the siren content is removed from the json response, but the response is still well formed, but incomplete, without any log in Mediator even in Debug mode.
Is it a Mediator problem, an axis one, or anything else ?
Aftere searching in Empower knowledge base, I've found this :
If the Content-Type header field specifies a content type for which no content
handler has been registered, Integration Server uses the default content
handler (ContentHandler_Default), which treats the content as text/html.
This explains why I have to change the content-types.xml file in the config directory of the WmMediator package.
Secondly, I've found that issue :
SMGME-6616 (Fix 18)
MultiRoot node elements of JSON type are not passed for a custom content type.
When a custom content type for JSON is executed and a multi root node
element is passed as a request for virtual rest API, then only the first
node is passed to the backend native API. This issue is resolved.
This seems a good explanation why I don't have the full content of my response, because with the Siren Hypermedia format, we have multiple roots in the json message.
So, no solution except patching.
Edit:
After patching, the problem is resolved
I'm trying to use the SSIS OData Source component to connect to the CRM OData Endpoint, but it's giving me the following error:
For security reasons DTD is prohibited in this XML document. To enable DTD processing set the DtdProcessing property on XmlReaderSettings to Parse and pass the settings into XmlReader.Create method. (System.Xml)
Has anyone got this working before? Any tricks to prevent it from doing the DTD check?
The XML the service responds starts as the following:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<service xml:base="https://url.com/XRMServices/2011/OrganizationData.svc/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns="http://www.w3.org/2007/app">
So, the problem is that the SSIS OData Connection won't do the OAuth dance, and as such fails to cope with CRM.
What I did instead was use the RSSBus CRM component to connect.
playing with
crm online
azure active directory
ssis
C# (script component)
xml transformation
you can achieve it. Our company created a blog post for that.
sorry for not posting the whole solution here, it's kind of long
Part 1
Part 2
Hello WSO2 community and hello Stackoverflow,
my testing of the SOA suite starting from the ESB is going good: now the ESB recognises external services, create correct proxies that return correct results.
SOLVED
About that, I have two issues: the first is that the "try it"
functionality raises the exception:
"Cannot find dispatch method for {http://schemas.xmlsoap.org/soap/envelope/}Envelope
[tagOpened]/soapenv:Text[tagClosed]"
when i try to send a SOAP enveloped created for the mock service of
the web service proxied.
Anyway, if I try the proxy service from an external client (created on
Netbeans) it works great.
ANSWER
For the first part, the reason is most probably the cross domain issue as try-it is sending messages through a java script stub from
the browser. You will notice that this works great when the service
itself is hosted in the ESB itself, because the request passes through
the same domain. This is why, although, it works perfectly through a
normal client invocation, it does not work through try-it.
The second issue is that I'm not able to orchestrate two services. My objective is sending the input of the first service to the second service, and then to the user.
I'm working on the tutorial Tharindu Mathew suggested: everything now makes sense to me except on one thing: the XSLT transformation.
Here is the out sequence the tutorial suggests you to create:
<outSequence xmlns="http://ws.apache.org/ns/synapse">
<switch source="get-property('STATE')">
<case regex="PERSON_INFO_REQUEST">
<log level="full">
<property name="sequence" value="outSequence - STATE 01 - response from PersonInfoService" />
</log>
<xslt key="xslt">
<property name="amount" expression="get-property('ORG_AMOUNT')" />
</xslt>
<log level="full">
<property name="sequence" value="outSequence - STATE 01 - request for CreditService" />
</log>
<property name="STATE" value="CREDIT_REQUEST" />
<send>
<endpoint key="CreditEpr" />
</send>
</case>
<case regex="CREDIT_REQUEST">
<log level="full">
<property name="sequence" value="outSequence - STATE 02 - response from CreditService" />
</log>
<send />
</case>
</switch>
</outSequence>
Now, focusing on the XSLT node of the first case of the switch, you can see that there's just a get for the amount property.
So that I think we have an XML from the in sequence that states the ID, and this get on the amount property (and I don't know what it does).
The tutorial then suggests:
To create the request to this CrediService, we use the following XSLT with the XSLT mediator. Note, we are using the ORG_ID that we stored in this XSLT as a XSLT parameter and using the XSLT mediator as well.
And here is the XSLT showed in the tutorial:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
xmlns:ns="http://samples.esb.wso2.org"
xmlns:ax21="http://samples.esb.wso2.org/xsd"
exclude-result-prefixes="ns fn">
<xsl:param name="amount"/>
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="//ns:getResponse" />
</xsl:template>
<xsl:template match="ns:getResponse" xmlns:ns="http://samples.esb.wso2.org">
<sam:credit xmlns:sam="http://samples.esb.wso2.org" xmlns:xsd="http://samples.esb.wso2.org/xsd">
<sam:info>
<xsd:amount><xsl:value-of select="$amount"/></xsd:amount>
<xsd:personInfo>
<xsd:address><xsl:value-of select="ns:return/ax21:address"/></xsd:address>
<xsd:id><xsl:value-of select="ns:return/ax21:id"/></xsd:id>
<xsd:name><xsl:value-of select="ns:return/ax21:name"/></xsd:name>
</xsd:personInfo>
</sam:info>
</sam:credit>
</xsl:template>
</xsl:stylesheet>
I was asked to put a similar file into the resources directory of WSO2 ESB, but this file is never used in the tutorial:
Copy the personToCredit.xslt in the sample zip to resources directory of WSO2 ESB.
---------LITTLE PARENTHESIS-----------
The WSDL file was not used either after it was stated:
Copy the CreditProxy.wsdl in the sample zip to the resources directory of the WSO2 ESB.
I cannot find the WSDL file in the Configuration/Governance Registry, and I don't know how to address it, so I chose to specify it inline instead.
---------LITTLE PARENTHESIS END-----------
This sentence is followed by the XSLT file text. My main question now is:
Where should I put this XSLT? I do not know where to put the XSLT mediator, neither how to build it.
Should I rely on registries?
A perfect answer could be the code of the out sequence, and the specified connection with the XSLT mediator suggested.
OverTheBitStair
Hi OverTheBitStair (nice nick!),
For the first part, the reason is most probably the cross domain issue as try-it is sending messages through a java script stub from the browser. You will notice that this works great when the service itself is hosted in the ESB itself, because the request passes through the same domain. This is why, although, it works perfectly through a normal client invocation, it does not work through try-it.
For the second part, the short answer is yes, it is possible. In terms of the ESB, we refer to it as a light-weight orchestration engine in addition to being a mediation engine. This means for light-weight and short-lived (<1 day) processes we can solve the orchestration requirements using the ESB without bringing in the Business Process Server.
To do this, we use this method called service chaining. What it does is introduce a method to get some output out of the initial service invocation and use it in a subsequent invocation. The article WSO2 ESB by example - Service Chaining should help you with implementation details on what you are looking for.
Hope this helps.
If you create a service chaining scenario where your proxy service calls two other services and return the result to the caller of the proxy service, it would look something like this:
Caller --> Proxy Service -- seq_A --> Service1 -- seq_B --> Service2 -- seq_C --> (proxy serviced response) --> Caller
In this case, seq_A would be the in sequence of the proxy service, seq_C the out sequence of the proxy service and seq_B another named sequence.
Input, i.e. the message body, to seq_A would be the input to proxy service. seq_A would contain a send mediator at the end and at that point in the sequence the message context would be the input to Service1. The send mediator also points to seq_B to be executed for the reply.
At start of seq_B the message body contains the output from Service1. If you want to keep some message data from before the service call you need to save that in properties in the context.
At the end of seq_B you would have a send mediator; at that point the message body should contain the input to Service2, The send mediator would in this case not need to point to an explicit reply sequence, if seq_C is the out sequence of the proxy service - that one will be used by default then.
When seq_C is executing the message body at that point is the response from Service2. Again, if you need to use/combine with some data prior to the call to Service2, you need that to be saved into properties.
Depending on the particular needs for the input and transformations needed at each step it can be fairly straightforward or a bit cumbersome to handle.
What also should taken into consideration is what needs to happen in error scenarios, as this may add some additional complexity, depending on the requirements.
I am creating some services using JAX-RS that need to take in arbitrarily complex objects as arguments, not just primitives like integers and strings. A discussion on the CXF mailing list says to just use a wrapper object as a single parameter in this case.
My concern is how to document the input format to the service? If creating a service that looks something like the following:
#POST
#Produces("application/json")
#Consumes("application/json")
#Path("oneParam")
public ComplexObject2 myServiceMethod(ComplexObject1 obj) {
Foo f = obj.foo
Bar b = obj.bar
...
}
the auto-generated WADL that CXF produces will only produce the following:
<resource path="/oneParam">
<method name="POST">
<request>
<representation mediaType="application/json"/>
</request>
<response>
<representation mediaType="application/json"/>
</response>
</method>
</resource>
This contains no information on what the request or response actually contains. Sergey on the CXF mailing list said it was possible to link a schema to the representation, but how am I supposed to do that? And how do I create the XSD?
(P.S. Using POST for idempotent resources might not be RESTful, but it's not important here as we are in essence doing RPC using Json. This is more or less a 1:1 clone of an existing SOAP based api.)
It is possible to link an XSD file into a WADL file and then to reference an XML element in the representation for requests and responses. However, as it is XML schema it doesn't apply to JSON representations.
To link an XSD into a WADL file, create a grammars element at the top of the file before the main resources element.
<grammars>
<include href="myapp.xsd"/>
</grammars>
Then add a reference to an XML element as follows (using a modified version of your example):
<resource path="/oneParam">
<method name="POST">
<request>
<representation mediaType="application/xml" element="myapp:oneParamRequest" />
</request>
<response>
<representation mediaType="application/xml" element="myapp:oneParamResponse" />
</response>
</method>
</resource>
The prefix myapp is defined in the XSD and can be used in the WADL file as well.
I don't know to to configure CXF to do this automatically. My experience with Jersey is similar and we use the generated WADL as a starting point for hand-editing later.
I'm attempting to read a response from a web service call in a junit test running in Eclipse Galileo. I'm able to successfully receive responses except when the response is a SOAP fault. Then I get the following exception:
org.xml.sax.SAXParseException: Element type "SOAP:Text" must be followed by either attribute specifications, ">" or "/>"
I have validated the XML in LiquidXML Studio against the SOAP 1.2 schema and it checks out.
Here is the XML response that SAX appears to be choking on. It has been stripped to the minimum in an attempt to eliminate anything obvious (I even made sure it didn't have any self closing elements):
<SOAP:Envelope xmlns:SOAP="http://www.w3.org/2003/05/soap-envelope" xmlns:SOAP_ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP:Header>
</SOAP:Header>
<SOAP:Body>
<SOAP:Fault>
<SOAP:Code>
<SOAP:Value>SOAP:Sender</SOAP:Value>
<SOAP:Subcode>
<SOAP:Value>SOAP:Sender</SOAP:Value>
</SOAP:Subcode>
</SOAP:Code>
<SOAP:Reason>
<SOAP:Text xml:lang="">
</SOAP:Text>
</SOAP:Reason>
<SOAP:Node>
</SOAP:Node>
<SOAP:Role>
</SOAP:Role>
<SOAP:Detail>
</SOAP:Detail>
</SOAP:Fault>
</SOAP:Body>
</SOAP:Envelope>
Any help would be appreciated.
Its obviously not regcognising 'xml:lang=""' as an attribute. CHeck with your xsd or xmlSchema what attributes are valid. Also you should be using
xml:lang=""
rather than "" although most parsers forgive you for this.
I think the problem is in mapping the soap fault xml to its corresponding object.
It turns out the problem was related to a tool I was using to return static string responses to web service requests. The static response XML contained the xml:lang attribute. However, when the tool was returning the static string, it was modifying it on the way out and replacing xml:lang on-the-fly with the fully qualified namespace equivalent {http://www.w3.org/XML/1998/namespace}lang. When this response was received, the SAXParser was choking because it couldn't interpret the fully qualified equivalent.
The tool returning the static responses used a Groovy xml parser as an integral part of sending the response.
The XmlParser Groovy class has a constructor that I had to change to set validating and namespaceAware attributes to false. So instead of XmlParser(), the tool now calls XmlParser(false, false).
Problem solved.
Thanks for the responses.