I don't know if this is even possible, I've been looking around and haven't found anything even related to this... or maybe I'm just not using the right terms to find it.
The problem is this.. let's say I have this request:
<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope/" soap:encodingStyle="http://www.w3.org/2003/05/soap-encoding" xmlns:xsd="http://request.dto.webservices.com/xsd">
<soap:Header/>
<soap:Body>
<impl:testServiceMethod>
<xsd1:booleanField1>?</xsd1:booleanField1>
</impl:testServiceMethod>
</soap:Body>
</soap:Envelope>
What's currently happening is that on the back-end side the booleanField1 (which is Boolean), is received as false instead of null. To get the null I have to remove the field from the request.
Is there a way to set anywhere on the code that behavior?
Related
When should we use SOAP and when should we use REST?
Can someone give a justifiable answer to this.
This was asked during an interview. I said it's up to contract with other parties. I don't know whether this is right or wrong. Can someone help with this.
SOAP I mean structure like below.
<?xml version='1.0' Encoding='UTF-8' ?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Header>
<m:reservation xmlns:m="http://travelcompany.example.org/reservation"
env:role="http://www.w3.org/2003/05/soap-envelope/role/next">
<m:reference>uuid:093a2da1-q345-739r-ba5d-pqff98fe8j7d</m:reference>
<m:dateAndTime>2007-11-29T13:20:00.000-05:00</m:dateAndTime>
</m:reservation>
<n:passenger xmlns:n="http://mycompany.example.com/employees"
env:role="http://www.w3.org/2003/05/soap-envelope/role/next">
<n:name>Fred Bloggs</n:name>
</n:passenger>
</env:Header>
<env:Body>
<p:itinerary xmlns:p="http://travelcompany.example.org/reservation/travel">
<p:departure>
<p:departing>New York</p:departing>
<p:arriving>Los Angeles</p:arriving>
<p:departureDate>2007-12-14</p:departureDate>
<p:departureTime>late afternoon</p:departureTime>
<p:seatPreference>aisle</p:seatPreference>
</p:departure>
<p:return>
<p:departing>Los Angeles</p:departing>
<p:arriving>New York</p:arriving>
<p:departureDate>2007-12-20</p:departureDate>
<p:departureTime>mid-morning</p:departureTime>
<p:seatPreference></p:seatPreference>
</p:return>
</p:itinerary>
</env:Body>
</env:Envelope>
In very few words, using REST you can describe the same operations you may expect from a database find, insert, update, delete. In REST such operation are paired with the HTTP command: GET, PUT, POST, DELETE. That's also why REST is referred as "state transfer" in the sense that you move objects in/out like in a database, in other words changing the state of your "model".
On the other hand SOAP reflect more a Remote Call Procedure (RPC) where, the message is heavily structured by XML, this means that in SOAP you do not simple transfer data but submit commands. In SOAP you can define, like in a programming language, methods and parameters. Regarding this last point to allow a client to use the "methods" (really are well structured XML messages, with name and parameters) defined by a SOAP service, the same service has to publish an XML document describing what messages and their format it can accept: if the method does not exists, it throws an error like "Service not supported".
I want to test my authorization-service via pact-jvm.
In my request I'm sending a html-body via post, including some metadata to verify the user - including his username and which is also sent in the header where I use Http Basic Auth. I add the header in my testclass with #TargetRequestFilter in my JUnit-Test after reading username+password from a configuration file.
This is because the application runs on different tiers. Every tier has another username+password combination. And the pact should work for every tier. Also when the user changes I only want to make little changes in my configuration file. It holds username, password, hostname, port and the protocol.
The problem is: I need to manipulate the html-body of the request depending on the content of my configuration file to match with the headers I set in my testclass without creating a new pact file every time.
So my question is: Is there a way to manipulate selective parts of the html-body I expect (via pact) from within the JUnit class?
Maybe there's another way to solve my problem I don't see yet.
Thanks in advance!
For clarity purpose an example of a Request:
<body>
<soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:body>
<ns2:authevalrequest1
xmlns:ns2="http://authgroup/authBRS/specification/ServiceView/AuthProvider/authBRS/">
<inputmetadata> <version>V_1_0_0</version> <metadataentry>
<key>US</key> <value>some_username</value> </metadataentry> <metadataentry>
<key>MA</key> <value>some_user_id</value> </metadataentry> </inputmetadata>
<request> <attrs> <type>String</type> <values>
<value>some_user_id</value> </values> <xacml>urn:oasis:names:tc:xacml:1.0:subject:subject-id</xacml>
</attrs> <attrs> <type>String</type> <values> <value>00</value>
</values> <xacml>http://thisisaservice.com/resource/dataRES</xacml>
</attrs> <attrs> <type>String</type> <values> <value>abc</value>
</values> <xacml>http://thisisaservice.com/subject/authprofilename</xacml>
</attrs> <attrs> <type>String</type> <values> <value>importData</value>
</values> <xacml>http://thisisaservice.com/resource/CompanyfunctionRES</xacml> </attrs>
</request>
</ns2:authevalrequest1>
</soap:body>
</soap:envelope>
</body>
I cannot change the provider or the consumer. I'm just here to make the verification work.
Edit: Maybe I forgot to say... I want to have the response bodies matching (actual and expected), what is no problem. But I need to modify the html-body of the request depending on my config-file.
The problem here is that you're trying to do validation of XML, which Pact does not currently support out of the box as we do all our validation using JSON. What you can do is simply use a string validator or a regex validator, however, if anything in your string changes (like white space), your tests might not validate.
At this point, you're kind of on your own for creating a way to template the output into a string to validate your interactions. We have looked at supporting XML, but there's simply very little interest.
I am looking for solution how to remove <soapenv:Header> part from SOAP request using XML-based routing (Apache Camel Blueprint XML).
So this:
<soapenv:Envelope xmlns:net="..." xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
...
</soapenv:Header>
<soapenv:Body>
...
</soapenv:Body>
</soapenv:Envelope>
shall become just this:
<soapenv:Envelope xmlns:net="..." xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
...
</soapenv:Body>
</soapenv:Envelope>
I think I found java-based solution, also xslt-based solution, but I dont find them quite suitable for my project, and I still hope there is some simple way how to do it directly in XML route without creating java processing class or adding XSLT template.
I was trying <removeHeaders pattern="_something_"/> but either I cant figure out the correct "something", or this command only applies to headers above payload section...
In Blueprint you can get the body of the XML by using XPATH. Something like this:
<setProperty propertyName="MessageBody">
<xpath>//*[local-name()='Body']</xpath>
</setProperty>
Then you could reconstruct your message with the envelop tag.
<setBody>
<simple><![CDATA[<Envelope>${property.MessageBody}</Envelope>]]></simple>
</setBody>
This will only work if your Envelope tag is a constant.
The easiest way I would thing is to parse the SOAP message and then remove the header. You can do that with SAAJ.
How to remove empty header from SOAP message?
.removeHeaders() is for removing Camel exchange headers which is something completely different.
It depends on what dataformat you are using for the CXF endpoint, Is this SOAP request coming from someother service ?
Why are you not happy with XSLT ?
Regardless, You can remove if you use payload DATAFORMAT.
So I find perfect and very simple solution to my issue:
The contents of <soapenv:Header> (along with contents of <soapenv:Body>) were stored in CxfPayload object , which is part of org.apache.camel.Exchange
After I learned this, I was just one Groovy command, that can be easily included in routes.xml, away from solution:
<groovy>
exchange.getIn().getBody(org.apache.camel.impl.DefaultMessage.class).getBody(org.apache.camel.component.cxf.CxfPayload.class).getHeaders().clear();
</groovy>
I'm trying to use the MTurk restful API, and POST to createHIT with a HITTypeID, however, I get the following error:
<?xml version="1.0"?>
<CreateHITResponse>
<OperationRequest>
<RequestId>199c9aff-86a4-4280-8d2f-d956a53515b0</RequestId>
</OperationRequest>
<HIT>
<Request>
<IsValid>False</IsValid>
<Errors>
<Error>
<Code>AWS.MissingParameters</Code>
<Message>Your request is missing required parameters. Required parameters include Question. Question is a required parameter. (1376962818123)</Message>
<Data>
<Key>Parameter</Key>
<Value>Question</Value>
</Data>
<Data>
<Key>Description</Key>
<Value>Question is a required parameter</Value>
</Data>
<Data>
<Key>Description</Key>
<Value>Question is a required parameter</Value>
</Data>
<Data>
<Key>Parameter</Key>
<Value>Question</Value>
</Data>
</Error>
</Errors>
</Request>
</HIT>
</CreateHITResponse>
From my understanding, title should not be required if Hittype is given. So it looks like the API is not actually viewing the POST body.
How would I work around this? Is there anything wrong with my request?
Request:
<CreateHITRequest>
<HITTypeId>HITTYPEID</HITTypeId>
<MaxAssignments>1</MaxAssignments>
<LifetimeInSeconds>604800</LifetimeInSeconds>
<Question><QuestionForm Structure></Question>
</CreateHITRequest>
You can't POST XML to Mechanical Turk over REST. It looks like you're confusing REST with SOAP to me.
Mechanical Turk's REST interface only takes URL-encoded key-value pairs, like this:
https://mechanicalturk.amazonaws.com/?Service=AWSMechanicalTurkRequester
&AWSAccessKeyId=[the Requester's Access Key ID]
&Version=2012-03-25
&Operation=CreateHIT
&Signature=[signature for this request]
&Timestamp=[your system's local time]
&HITTypeId=T100CN9P324W00EXAMPLE
&Question=[URL-encoded question data]
&LifetimeInSeconds=604800
I had mixed up the POST requests parameters.
For MTURK REST API, you do not POST the XML structure, but headers+values to the indicated URL.
Instead of URL params, you POST them as params in the POST body.
For example the GET request below:
GET https://mechanicalturk.amazonaws.com/?Service=AWSMechanicalTurkRequester
&AWSAccessKeyId=[the Requester's Access Key ID]
&Version=2012-03-25
&Operation=CreateHIT
&Signature=[signature for this request]
&Timestamp=[your system's local time]
&HITTypeId=T100CN9P324W00EXAMPLE
&Question=[URL-encoded question data]
&LifetimeInSeconds=604800
Would become:
POST https://mechanicalturk.amazonaws.com/?Service=AWSMechanicalTurkRequester
AWSAccessKeyId=[the Requester's Access Key ID]
&Version=2012-03-25
&Operation=CreateHIT
&Signature=[signature for this request]
&Timestamp=[your system's local time]
&HITTypeId=T100CN9P324W00EXAMPLE
&Question=[URL-encoded question data]
&LifetimeInSeconds=604800
Where everything below the URL is the POST body.
Hope this helps somebody.
i have implemented a webservice client that is used inside a webapplication (using Spring) and this client gets a response in which CXF bailsout and gives me an error message.
The error message is:
Server did not recognize the value of HTTP Header SOAPAction
I have found the problem but do not know what i can do to adjust my webservice response handling.
The xml response below works without any problems.
Works and is accepted ok!
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bar="http://www.dummyurl.com/service-v1.0/">
<soapenv:Header/>
<soapenv:Body>
<bar:StartSessionResponse>
<result>1</result>
</bar:StartSessionResponse>
</soapenv:Body>
</soapenv:Envelope>
The service actually returns:
Fails and gives me an error!
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<StartSessionResponse xmlns="www.dummyurl.com/service-v1.0/">
<result xmlns="">1</result>
</StartSessionResponse>
</soap:Body>
</soap:Envelope>
The difference as far as i can see is in the placing of the
xmlns="www.dummyurl.com/service-v1.0/ element, in the success xml it is in the enveloppe, in the failed xml it is on the reponse method.
Is there a way that i can convince CXF to accept the response? Or is the service giving back an abnormal result?
The service is giving back a wrong response in the second case, assuming that the first response is proper.
In the first case "www.dummyurl.com/service-v1.0/" is the namespace of your elements - StartSessionResponse, result is not qualified with the namespace. In the second case, the StartSessionResponse has the same namespace as the first sample, but the result has a different namespace altogether, taking out xmlns="" for result will make the xml consistent.