I'm starting to work on workday integration, when my first purpose is to retrieve all candidates\applicants that currently exist.
I copied the "Get_Candidates_Request" xml from the official documentation site (https://community.workday.com/sites/default/files/file-hosting/productionapi/Recruiting/v33.1/samples/Get_Candidates_Request.xml), fixed it so it will be valid (using soapui), but I'm still getting "invalid request" as response...
Does anyone ever worked with this operation and can give me a hand? What do I miss??
SOAP-ENV:Client.validationError
Invalid request
It's hard to say without seeing that fixed up request, but here's a quick example of a request that would retrieve all candidates that applied after the first of the year. I hope that this able to get your moving in the right direction.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bsvc="urn:com.workday/bsvc">
<soapenv:Header>
<bsvc:Workday_Common_Header>
<bsvc:Include_Reference_Descriptors_In_Response>true</bsvc:Include_Reference_Descriptors_In_Response>
</bsvc:Workday_Common_Header>
</soapenv:Header>
<soapenv:Body>
<bsvc:Get_Candidates_Request bsvc:version="v33.0">
<bsvc:Request_Criteria>
<bsvc:Applied_From>2019-01-01T00:00:00</bsvc:Applied_From>
</bsvc:Request_Criteria>
</bsvc:Get_Candidates_Request>
</soapenv:Body>
</soapenv:Envelope>
Related
I am using karate for SOAP API services. How can I declare a global variable ?? as you can see in below feature file? after print response I have variable name def ourSession = /Envelope/Body/LoginReturn I am using this variable (ourSession) in next scenario but it's failing ? but it's not global.
So how can I declare "ourSession" as a global variable ?? so I can use into other scenarios?
Any help will be highly appreciated. Please have a look of my feature file below;
#
Feature:
SOAP calls to the following service:
Background:
* url baseUrl
* def configSS = Java.type('practice.utilities.Shellscripts')
##################################### LOG IN #########################################################
#DataAcquisition
Scenario: login
Given request
"""
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsh="http://www.informatica.com/wsh">
<soapenv:Header/>
<soapenv:Body>
<wsh:Login>
<RepositoryDomainName>Domain_Aqr_Dev_Powercenter</RepositoryDomainName>
<RepositoryName>Powercenter_Repository_Service</RepositoryName>
<UserName>#(AM_USERNAME)</UserName>
<Password>#(AM_PASSWORD)</Password>
<UserNameSpace/>
</wsh:Login>
</soapenv:Body>
</soapenv:Envelope>
"""
When soap action '/login'
Then assert responseStatus == 200
And print 'response: ', response
* def ourSession = /Envelope/Body/LoginReturn
* print ourSession
Do not create a new scenario for the subsequent call. A single scenario can have multiple requests.
i am using this variable (ourSession) in next scenario
You can't. There are many answers in Stack Overflow addressing this question, please find them and read them.
And please read the docs: https://github.com/intuit/karate#script-structure
To quote:
if you are expecting a variable in the Background to be modified by one Scenario so that later ones can see the updated value - that is not how you should think of them, and you should combine your 'flow' into one scenario.
There are many ways to "re-use" in Karate such as call. So you should be able to figure out how to do what you want.
Now if you really want a "global" variable, please use callonce that is most likely what you are looking for:
I have a Ruby (2.6.5) on Rails (5.2.3) application which is already successfully using Savon (2.12) to interact with FlightAware's FlightXML 2 API via SOAP/WSDL. However, I'm running into an issue while attempting to write Minitest tests for this functionality, using WebMock (3.7.6) to stub out the API requests.
My application (via Savon) makes a request including an XML body like the following example:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:FlightXML2="http://flightxml.flightaware.com/soap/FlightXML2" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Body>
<FlightXML2:AirportInfoRequest>
<FlightXML2:airportCode>KDFW</FlightXML2:airportCode>
</FlightXML2:AirportInfoRequest>
</env:Body>
</env:Envelope>
I would like to use a with statement so that the stub only responds to a request having a specific airport code in the element. For example, if I'm looking for "KDFW", then a request containing <FlightXML2:airportCode>KDFW</FlightXML2:airportCode> should match, but a request containing <FlightXML2:airportCode>CYYZ</FlightXML2:airportCode> should not.
Right now, I have it working by including the XML tag in a regular expression:
icao_code = "KDFW"
response_body = "[the response I want]"
WebMock.stub_request(:post, "http://flightxml.flightaware.com/soap/FlightXML2/op").
with(body: /<FlightXML2:airportCode>#{icao_code}<\/FlightXML2:airportCode>/).
to_return(status: 200, body: response_body)
This feels like a kludge, especially when the documentation for WebMock mentions that I can use hash_including to match XML tags. No matter what I try, though, I get the typical WebMock unregistered request error, indicating that I don't match the request. Here are the with statements that I've tried so far:
with(body: hash_including({airport_code: icao_code})
with(body: hash_including({"airportCode": icao_code})
with(body: hash_including({"FlightXML2:airportCode": icao_code})
How can I match a specific XML element without having to resort to putting the XML tag in a regular expression?
Match the request against a block:
stub_request(:post, "http://flightxml.flightaware.com/soap/FlightXML2/op")
.with do |request|
# do something
end.to_return(status: 200, body: response_body)
The block code could look something like:
request_xml = Nokogiri::XML(request.body)
request_xml.xpath("//FlightXML2:airportCode").any? do |node|
node.content == icao_code
end
This approach has an additional advantage in that you can insert a debugger into the above code block and figure out why your test case isn't working. You can see Webmock docs here.
I have a problem with transform message. I need to recieve messages in SOAP/WSDL sistem. In my case i have this structure for process the responses.
This is my flow and in trnasform message component i have this problem:
Y put credentials in transform message but if i see the web service component, say that payload is unknown.
The problem is the sem for two transform message. I don't know how can i do to put the credentials good for doing a reception message aplication with SOAP/WSDL sistem.
Thanks for help.
Please try to log the payload as [message.payloadAs(java.lang.String)]
If you can see the actual payload in XML or JSON format whatever you are POSTing, then extract the specific elements.
If your GET then in query params retrieve them using [message.inboundProperties.'httpqueryparams']
Extract the specfic elements into flowvars and set them to Webservice consumer add [flowVars.userid] and [flowVars.pwd]
That will echo back as response.
I hope this is going to help.
Bit of a guess here because you haven't shown exactly what your WSDL is expecting:
I think you may want a transform a bit like this
%dw 1.0
%output application/xml encoding="UTF-8"
---
{
gdspHeader #(xmlns: "http://ws.gdsp.vf.gdspcustomer.com/" ) :{
gsdpCredentials: {
password: "Mule",
userId: "Monty"
}
}
}
Which transforms to
<?xml version='1.0' encoding='UTF-8'?>
<gdspHeader xmlns="http://ws.gdsp.vf.gdspcustomer.com/">
<gsdpCredentials>
<password>Mule</password>
<userId>Monty</userId>
</gsdpCredentials>
</gdspHeader>
I'm using the following feature file and it generates the response. How can we store the response into an XML file instead of showing the console?
Feature File:
Feature: Test soap end point
Background:
* url 'sample url'
Scenario: SmokeTest
Given request read('getMbrWksMembershipDetails.xml')
When soap action 'test url'
Then status 200
And print response
EDITED: The response I'm getting like this.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:getMbrWksMembershipDetailsResponse xmlns:ns1="xxxxxxxxxx">
<ns4:WksMembershipSummaryResponse xmlns:ns2="xxxxxxxx" xmlns:ns3="xxxxxxxxxx" xmlns:ns4="xxxxxxxxxx">
<ns2:customerSummary>
<ns2:address>
<ns2:city>SOUTH CHESTERFIELD</ns2:city>
<ns2:country>USA</ns2:country>
<ns2:isoCountryCode>US</ns2:isoCountryCode>
<ns2:line1>9998, N. MICHIGAN ROAD.</ns2:line1>
<ns2:postalCode>23834</ns2:postalCode>
<ns2:state>VA</ns2:state>
</ns2:address>
<ns2:allowPasswordChange>true</ns2:allowPasswordChange>
<ns2:arpMember>false</ns2:arpMember>
<ns2:brandCode>ABC</ns2:brandCode>
<ns2:brandId>1</ns2:brandId>
<ns2:companyCode>ABC</ns2:companyCode>
<ns2:eliteMemberRewardStatus>false</ns2:eliteMemberRewardStatus>.....
Question:
How can I validate the tag values from this response?
Thanks,
First a question - why do you want to do this ? Karate is a testing framework, and besides being able to run assertions on responses, you can easily re-use responses (or some data from a response) in the next request. There is no need to ever save anything to a file.
And if you follow the instructions in the Karate documentation on logging you will also see responses logged to the file target/karate.log.
When you use the JUnit runner, you will see all responses in an HTML report.
Same case with the parallel runner.
Anyway, even after all this if you really really want to save responses to a file, use Java interop and write your own utility to save to a file, it will be a just a few lines of code. It is not built-in to Karate because of the above reasons.
EDIT: well, after all the typing above, turns out you just want to know how to validate (assert / match) the response ? Great, that is the whole selling point of Karate.
I assume you have read the Karate documentation. Also refer this example: soap.xml and this one for more ideas: xml.feature
Anyway here are some hints based on your XML sample to get you started. You can paste the below into a Scenario: and run this without needing to make HTTP requests and that way test and get comfortable with match:
* def response =
"""
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:getMbrWksMembershipDetailsResponse xmlns:ns1="xxxxxxxxxx">
<ns4:WksMembershipSummaryResponse xmlns:ns2="xxxxxxxx" xmlns:ns3="xxxxxxxxxx" xmlns:ns4="xxxxxxxxxx">
<ns2:customerSummary>
<ns2:address>
<ns2:city>SOUTH CHESTERFIELD</ns2:city>
<ns2:country>USA</ns2:country>
<ns2:isoCountryCode>US</ns2:isoCountryCode>
<ns2:line1>9998, N. MICHIGAN ROAD.</ns2:line1>
<ns2:postalCode>23834</ns2:postalCode>
<ns2:state>VA</ns2:state>
</ns2:address>
</ns2:customerSummary>
</ns4:WksMembershipSummaryResponse>
</ns1:getMbrWksMembershipDetailsResponse>
</soap:Body>
</soap:Envelope>
"""
* match //address/city == 'SOUTH CHESTERFIELD'
* match //customerSummary/address ==
"""
<ns2:address>
<ns2:city>SOUTH CHESTERFIELD</ns2:city>
<ns2:country>USA</ns2:country>
<ns2:isoCountryCode>US</ns2:isoCountryCode>
<ns2:line1>9998, N. MICHIGAN ROAD.</ns2:line1>
<ns2:postalCode>23834</ns2:postalCode>
<ns2:state>VA</ns2:state>
</ns2:address>
"""
I'm writing a WCF service that receives events. It's to an agreed standard so I've got to stick to the service definition, and I don't control the data the clients send. Again this is to an agreed standard although the data can vary.
Here's one of the methods on my service:
complexType ErrorEvent(int requestId, complexType returnValue, ref string errorInfo)
Clients send XML in the errorInfo string that my function will manipulate and return.
The data I get is like this (full SOAP request):
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ErrorEvent xmlns="http://blah">
<requestId>1</requestId>
<returnValue>
<returnCode>0</returnCode>
</returnValue>
<errorInfo>
<ErrorMessage>An error message</ErrorMessage>
<DefaultTask><!-- Complex data --></DefaultTask>
<Task><!-- Complex data --></Task>
<Task><!-- Complex data --></Task>
<Task><!-- Complex data --></Task>
<ExtraMessage>hello</ExtraMessage>
<ExtraMessage>world</ExtraMessage>
</errorInfo>
</ErrorEvent>
</s:Body>
</s:Envelope>
However, when I try and run this I get this error (edited):
The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter errorInfo. The InnerException message was 'There was an error deserializing the object of type System.String. End element 'errorInfo' from namespace '' expected. Found element 'ErrorMessage' from namespace ''.
So my question is, is there any way I achieve what I want to do without altering the signature of my method? For example adding attributes to my service etc? Or do I need to intercept the message?
Thanks for any pointers.
Does it have to be passed as a string? You know you can also receive XmlElement and XElements in WCF?
Are you generating the SOAP request yourself? Could you use a CDATA section, i.e.
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ErrorEvent xmlns="http://blah">
<requestId>1</requestId>
<returnValue>
<returnCode>0</returnCode>
</returnValue>
<errorInfo>
<![CDATA[<ErrorMessage>An error message</ErrorMessage>
<DefaultTask><!-- Complex data --></DefaultTask>
<Task><!-- Complex data --></Task>
<Task><!-- Complex data --></Task>
<Task><!-- Complex data --></Task>
<ExtraMessage>hello</ExtraMessage>
<ExtraMessage>world</ExtraMessage>]]>
</errorInfo>
</ErrorEvent>
</s:Body>
</s:Envelope>
I didn't find a way to make this work and as #luksan says, it's a misuse by a client to send unescaped XML to a string parameter.
The workaround I adopted was to make a class that implements IClientMessageInspector, IDispatchMessageInspector and IEndpointBehavior to intercept, check and modify any messages that were incorrect.
If I could have changed the interface, another workaround would have been to accept XmlNode[] instead of string.