I had to fiddle with a WSDL document for one of the implementations and I came across Scalaxb! I'm now trying to generate some scala classes from the WSDL file that I have and as expected I'm hitting into some issues:
Here is a snippet of the WSDL file:
<?xml version="1.0" encoding="UTF-8" ?>
<wsdl:definitions
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.myservice.com/MyServices/2012/06/18/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:s="http://www.w3.org/2001/XMLSchema"
name="MyServices"
targetNamespace="http://www.myservice.com/MyServices/2012/06/18/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://www.myservice.com/MyServices/2012/06/18/">
<s:complexType name="UserCredentials">
<s:sequence>
<s:element name="UserName" type="s:string" />
<s:element name="Password" type="s:string" />
</s:sequence>
</s:complexType>
<s:element name="UserCredentials" type="tns:UserCredentials" />
<s:complexType name="AnotherComplexType" >
<s:sequence>
<s:element name="Index" type="s:int" />
<s:element name="Name" type="s:string" />
<s:element name="Status" type="s:boolean" />
</s:sequence>
</s:complexType>
....
Assume that the rest of the WSDL file is completely fine, when I tried to compile the project, I hit the following error:
[error] /Users/joe/Desktop/scalaxb-soap-example/target/scala-2.11/src_managed/main/sbt-scalaxb/myservice/xmlprotocol.scala:1542: not found: value userCredentials
[error] scalaxb.toXML(userCredentials, Some("http://www.myservice.com/MyServices/2012/06/18/"), "UserCredentials", defaultScope), defaultScope, baseAddress, "POST", Some(new java.net.URI("http://1.1.1.1/cgi-bin/cgi.cgi?WebService=SetGPTimerChannel"))).transform({ case (header, body) =>
[error] ^
[error] /Users/joe/Desktop/scalaxb-soap-example/target/scala-2.11/src_managed/main/sbt-scalaxb/myservice/xmlprotocol.scala:1544: value toSeq is not a member of Any
[error] scala.xml.Elem(null, "Body", scala.xml.Null, defaultScope, true, body.toSeq: _*)
[error] ^
[error] /Users/joe/Desktop/scalaxb-soap-example/target/scala-2.11/src_managed/main/sbt-scalaxb/myservice/xmlprotocol.scala:1551: not found: value userCredentials
[error] scalaxb.toXML(userCredentials, Some("http://www.myservice.com/MyServices/2012/06/18/"), "UserCredentials", defaultScope), defaultScope, baseAddress, "POST", Some(new java.net.URI("http://1.1.1.1/cgi-bin/cgi.cgi?WebService=SomeServiceCall"))).transform({ case (header, body) =>
[error] ^
[error] /Users/joe/Desktop/scalaxb-soap-example/target/scala-2.11/src_managed/main/sbt-scalaxb/myservice/xmlprotocol.scala:1553: value toSeq is not a member of Any
[error] scala.xml.Elem(null, "Body", scala.xml.Null, defaultScope, true, body.toSeq: _*)
[error] ^
Any ideas what and why I'm facing this issue? Here is my build.sbt:
import ScalaxbKeys._
val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "1.0.2"
val scalaParser = "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.1"
val dispatchV = "0.11.1" // change this to appropriate dispatch version
val dispatch = "net.databinder.dispatch" %% "dispatch-core" % dispatchV
organization := "com.eon"
name := "scalaxb-myservice-sample"
scalaVersion := "2.11.6"
scalaxbSettings
packageName in (Compile, scalaxb) := "rdmservice"
dispatchVersion in (Compile, scalaxb) := dispatchV
async in (Compile, scalaxb) := true
sourceGenerators in Compile <+= scalaxb in Compile
libraryDependencies ++= Seq(scalaXml, scalaParser, dispatch)
If you only need to generate WSDL client code, using scalaxb might be a bit too much. As an option, you could just use wsimport wrapped as a simple SBT task that would be executed before the main code compilation. Apart from one less dependency, it also keeps your repository pristine and frees it from committing the generated boilerplate Java code. Here's a sample template project if anyone is interested: https://github.com/sainnr/sbt-scala-wsdl-template.
Related
There is an external SOAP server that I'm trying to connect and make requests using the python-django framework with the zeep library.
The WSDL dump is as follows:
Prefixes:
xsd: http://www.w3.org/2001/XMLSchema
ns0: http://tempuri.org/
Global elements:
ns0:GetJobCards(key: xsd:string, technicianID: xsd:string, jobCardNumber: xsd:string, jobcards: ns0:ArrayOfJobCardsEnt, message: xsd:string)
ns0:GetJobCardsResponse(GetJobCardsResult: xsd:boolean, jobcards:ns0:ArrayOfJobCardsEnt, message: xsd:string)
Global types:
xsd:anyType
ns0:ArrayOfJobCardsEnt(JobCardsEnt: {schema: , _value_1: ANY}[])
xsd:ID
xsd:IDREF
xsd:IDREFS
xsd:NCName
xsd:NMTOKEN
xsd:NMTOKENS
xsd:NOTATION
xsd:Name
xsd:QName
xsd:anySimpleType
xsd:anyURI
xsd:base64Binary
xsd:boolean
xsd:byte
xsd:date
xsd:dateTime
xsd:decimal
xsd:double
xsd:duration
xsd:float
xsd:gDay
xsd:gMonth
xsd:gMonthDay
xsd:gYear
xsd:gYearMonth
xsd:hexBinary
xsd:int
xsd:integer
xsd:language
....
Bindings:
Soap11Binding: {http://tempuri.org/}CallSoap
Soap12Binding: {http://tempuri.org/}CallSoap12
Service: Call
Port: CallSoap (Soap11Binding: {http://tempuri.org/}CallSoap)
Operations:
GetJobCards(key: xsd:string, technicianID: xsd:string,
jobCardNumber: xsd:string, jobcards: ns0:ArrayOfJobCardsEnt,
message: xsd:string) -> GetJobCardsResult: xsd:boolean,
jobcards: ns0:ArrayOfJobCardsEnt, message: xsd:string
....(some other operations)
One of the calls is to get a list of jobCards with the following schema
<s:element name="GetJobCards">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="key" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="technicianID" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="jobCardNumber" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="jobcards" type="tns:ArrayOfJobCardsEnt"/>
<s:element minOccurs="0" maxOccurs="1" name="message" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="ArrayOfJobCardsEnt">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="JobCardsEnt" nillable="true">
<s:complexType>
<s:sequence>
<s:element ref="s:schema"/>
<s:any/>
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
When I make the call using Postman I send the following request and it works:
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetJobCards xmlns="http://tempuri.org/">
<key>some_valid_key</key>
<technicianID>some_technician_id</technicianID>
<jobCardNumber></jobCardNumber>
<jobcards></jobcards>
<message>""</message>
</GetJobCards>
</soap:Body>
Please note that the values for "jobCardNumber" and "jobcards" need to be empty to get all the jobCards. But I cannot seem to replicate this same call using the zeep library.
Here is what I have tried.
1 - tried adding xsd.SkipValue for the empty values
request_data = {
'key': some_valid_key,
'technicianID': some_technician_ID,
'jobCardNumber': xsd.SkipValue,
'jobcards': xsd.SkipValue,
'message': ''
}
response_body = client.service.GetJobCards(**request_data)
2 - setting the values to Nil
from zeep.xsd import Nil
jobCardEnt = client.get_type('ns0:ArrayOfJobCardsEnt')
jobCardEnt = jobCardEnt()
request_data = {
'key': some_valid_key,
'technicianID': some_technician_ID,
'jobCardNumber': Nil,
'jobcards': Nil,
'message': ''
}
response_body = client.service.GetJobCards(**request_data)
None of these seems to works and I'm not sure how to get it to work.
Can someone please guide me on this?
Thanks in advance!
Here is how I got it working
with self.client.settings(strict=False):
response_body = self.client.service.GetJobCards(
key=some_valid_key,
technicianID=some_technician_id,
message=''
)
And omitted the values for 'jobCardNumber' and 'jobcards'
I have been using Authorize.NET's GetCustomerProfile for many years and suddenly today the response is not returning a payment profile. It just returns an array of profiles, but all important fields (such as payment) are null.
(This is part of their CIM feature where an 'obfuscated' payment profile is returned and should be something like XXXX1234)
I am using a generated proxy within Visual Studio to the URL https://api.authorize.net/soap/v1/Service.asmx?WSDL (which generates a References.cs file)
I had a similar issue on the CreateCustomerPaymentProfile SOAP call (via .NET auto-generated proxy) that just started yesterday, 11/3/2015, even though we've been successfully interfacing the SOAP CIM for a couple years.
I was able to "fix" the issue by doing an "Update Service Reference" in Visual Studio to regenerate the proxy classes based on their latest WSDL. There were several changes in the WSDL.
Specifically, on my end it appeared as if the response was not including a value for the customerPaymentProfileId after being successfully created on their end. In reality, they were in fact still sending this value, but there was a new field above it in the XML response, customerProfileId. As Simon_Weaver mentioned in his answer, the proxy classes generated by Visual Studio have explicit ordering of fields that are required for proper deserialization. The addition of this previously "unknown" field above a known field caused it to break my code.
Luckily this new customerProfileId was included in their latest WSDL so an "Update Service Reference" and recompile fixed my issue.
I informed Authorize.net support of my issue in great detail and told them they need to include any new fields at the end of the "sequence" in the WSDL document in order to not break and clients using older versions of the WSDL. So far I have not heard a response from them, but I would encourage anyone else who experienced this issue, even if you've already worked-around it, to report it to them at support#authorize.net so they don't accidently do this again.
Well hello Simon!
It looks like Authorize.NET updated their service with new fields but forgot to add them to the WSDL.
This is a sample request that I sent (intercepted using Fiddler):
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo3vYq2eC/5VIuiUcm2hEtw8AABBBJr/dLQF7z02Y7UKwphq24W1n9j0XlQ1MiAlOjy5fO14ACQAA</VsDebuggerCausalityData>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<GetCustomerProfile xmlns="https://api.authorize.net/soap/v1/">
<merchantAuthentication>
<name>95U6bwXXXXX</name>
<transactionKey>8tf62gV7XXXXXX</transactionKey>
</merchantAuthentication>
<customerProfileId>37745529</customerProfileId>
</GetCustomerProfile>
</s:Body>
</s:Envelope>
This is the response:
<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>
<GetCustomerProfileResponse xmlns="https://api.authorize.net/soap/v1/">
<GetCustomerProfileResult>
<resultCode>Ok</resultCode>
<messages>
<MessagesTypeMessage>
<code>I00001</code>
<text>Successful.</text>
</MessagesTypeMessage>
</messages>
<profile>
<merchantCustomerId>33938</merchantCustomerId>
<email>4691705#EXAMPLE.COM</email>
<customerProfileId>37745529</customerProfileId>
<paymentProfiles>
<CustomerPaymentProfileMaskedType>
<billTo>
<firstName>TEST</firstName>
<lastName>USER</lastName>
<company>Defender Razor</company>
<address>1 RODEO DRIVE</address>
<city>BEVERLY HILLS</city>
<state>CA</state>
<zip>90210</zip>
<country>UNITED STATES</country>
</billTo>
<customerProfileId>0</customerProfileId>
<customerPaymentProfileId>34313485</customerPaymentProfileId>
<payment>
<creditCard>
<cardNumber>XXXX5108</cardNumber>
<expirationDate>XXXX</expirationDate>
</creditCard>
</payment>
</CustomerPaymentProfileMaskedType>
</paymentProfiles>
</profile>
</GetCustomerProfileResult>
</GetCustomerProfileResponse>
</soap:Body>
</soap:Envelope>
Everything here is correct - as you can see the payment node is being sent correctly.
However - with .NET deserialization the order of attributes matters - as specified in the generated References.cs file.
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
It turns out that two new fields were added to the response billTo and customerProfileId but they weren't added to the WSDL.
So when trying to deserialize the field billTo is found but that isn't what was expected - so everything ends up null.
If you add these two lines (and be careful to add them to exactly this type) then you can regenerate the references.cs file (by right clicking on the service reference and regenerating the file).
If you were generating your proxy from the URL https://api.authorize.net/soap/v1/Service.asmx?WSDL then you will need to download this file locally as Service.wsdl and generate the proxy from there.
<s:element minOccurs="1" maxOccurs="1" name="billTo" type="tns:CustomerAddressType"/>
<s:element minOccurs="1" maxOccurs="1" name="customerProfileId" type="s:long" />
<s:complexType name="CustomerPaymentProfileMaskedType">
<s:complexContent mixed="false">
<s:extension base="tns:CustomerPaymentProfileBaseType">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="billTo" type="tns:CustomerAddressType"/>
<s:element minOccurs="1" maxOccurs="1" name="customerProfileId" type="s:long" />
<s:element minOccurs="1" maxOccurs="1" name="customerPaymentProfileId" type="s:long" />
<s:element minOccurs="0" maxOccurs="1" name="payment" type="tns:PaymentMaskedType" />
<s:element minOccurs="0" maxOccurs="1" name="driversLicense" type="tns:DriversLicenseMaskedType" />
<s:element minOccurs="0" maxOccurs="1" name="taxId" type="s:string" />
</s:sequence>
</s:extension>
</s:complexContent>
</s:complexType>
I lost over 12 hours of payments before this was detected. Fortunately I have the customer's emails but this was very bad. You can't just add fields to a response where the order matters. And even worse than that you can't just forget to add them to the WSDL.
This was the quick fix for me. I may switch to using the proper API at some point - and I've reported this to Authorize.net hoping they may respond too.
This is the differences in References.cs after I made my change. As you can see the Order property has been incremented :
I would like to make request to web service from mule flow. So far I got WSDL generate classes (wsdl2java), prepared flow (below), and "successfully" send request. Now, problem is, that even thou I have taken base class from generated class and put it in payload it does not generate required soap.
My flow:
<flow name="flow1" doc:name="flow1">
<quartz:inbound-endpoint jobName="testingJob" repeatInterval="10810000" repeatCount="0" startDelay="5000" responseTimeout="10000" doc:name="Quartz">
<quartz:event-generator-job groupName="g1job" jobGroupName="g1job">
<quartz:payload>a</quartz:payload>
</quartz:event-generator-job>
</quartz:inbound-endpoint>
<logger message="Starting quartz for testing purpouses" level="INFO" doc:name="Logger"/>
<custom-transformer class="com.example.GenerateSimpleRoutePublish" doc:name="Java"/>
<cxf:simple-client doc:name="SOAP" serviceClass="com.example.ws.MyWebService" operation="send">
</cxf:simple-client>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="9094" path="sync-server-web/services/myws" method="POST" connector-ref="http_internal" doc:name="HTTP"/>
</flow>
GenerateSimpleRoutePublish just put base object into payload and move on.
Result that is sent as soap request:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:send xmlns:ns1="http://somenamespace.si/">
<ns1:arg0>
<ns1:MyRequest>
...
But it should look like this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:send xmlns:ns1="http://somenamespace.si/">
<ns1:MyRequest>
...
Notice that is not there anymore in desired xml.
Anyone knows how to achieve that? I did googled a lot but just don't find right solution. If more is required then I can provide info.
Thanks!
EDIT
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="MyWebService" targetNamespace="http://ws.example.com/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://ws.example.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xs:schema elementFormDefault="unqualified" targetNamespace="http://ws.example.com/"
version="1.0" xmlns:tns="http://ws.example.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="MyRequest" type="tns:MyRequest" />
<xs:element name="send" type="tns:send" />
<xs:element name="sendResponse" type="tns:sendResponse" />
<xs:complexType name="send">
<xs:sequence>
<xs:element minOccurs="0" ref="tns:MyRequest" />
</xs:sequence>
</xs:complexType>
<xs:complexType final="extension restriction" name="MyRequest">
<xs:complexContent>
...
Transformer class GenerateSimpleRoutePublish.java:
#Override
public MuleEvent process(MuleEvent event) throws MuleException {
event.setMessage(transformMessage(event.getMessage(), event.getEncoding()));
// TODO Auto-generated method stub
return event;
}
public MuleMessage transformMessage(MuleMessage message, String outputEncoding) throws TransformerException {
MyRequest myRequest = new MyRequest();
/**
* some filling of testing data that is formatted correctly when soap is sent.
*/
Send send = new Send();
send.setMSyequest(myRequest);//the only setter method available for Send
message.setPayload(send);
return message;
}
Send.java methods and xml definition:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "send", propOrder = {"myRequest"})
public MyRequest getMyRequest()
public void setMyRequest(MyRequest value)
Instead of using a custom-transformer you could use Groovy script to send SOAP request to webservice client just as Java pojo class... Please check the reference :- https://m-square.com.au/consuming-net-wcf-soap-web-services-from-mule/
how can I prevent string argument from beeing parsed as xml ?
<s:element name="MyResponse">
<s:complexType>
<s:sequence>
<s:element type="s:string" name="xmlResultWithStringType" minOccurs="0" maxOccurs="1" />
</s:sequence>
</s:complexType>
</s:element>
in log I have a correct answer -
Hello xmlStart <foo>in foo<bar>in bar</bar> end foo</foo> xmlEnd
full log :
---[HTTP request - http://localhost:8080/mockXXX]---
Accept: application/soap+xml, multipart/related
Content-Type: application/soap+xml; charset=utf-8;action="http://xxx"
User-Agent: JAX-WS RI 2.2.7-b01 svn-revision#13316
<?xml version="1.0" ?><S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"><S:Body><MyRequest xmlns="http://fff"><xmlRequest>req do webserwisu</xmlRequest></MyRequest></S:Body></S:Envelope>--------------------
---[HTTP response - http://localhost:8080/mockXXX - 200]---
null: HTTP/1.1 200 OK
Content-Type: application/soap+xml;charset=UTF-8
Server: Jetty(6.1.x)
Transfer-Encoding: chunked
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:fff="http://fff">
<soap:Header/>
<soap:Body>
<fff:MyResponse>
<!--Optional:-->
<fff:XmlResultWithStringType>Hello xmlStart <foo>in foo<bar>in bar</bar> end foo</foo> xmlEnd</fff:XmlResultWithStringType>
</fff:MyResponse>
</soap:Body>
</soap:Envelope>--------------------
but webservice call returns only
xmlEnd2
whole beginning is lost, the content of XmlResultWithStringType is parsed by xml parser,
but it should not,
how can I prevent it from beeing parsed ?
I use jax-ws-RI implementation,
it should be but into CDATA section
<![CDATA[ any xml possible here, it won't be treated as xml but as string ]]>
otherwise, without CDATA, it is treated as xml not as string.
I have serached this question on Stackoverflow and found some similar questions but none of them solved my issue. I have compiled all the "proposed" solution but NOTHING works :-(
I have a wsdl and I generated the client code using adb client(Axis 2). The wsdl says that this request will be sent over Https url. I able to successfully create a stub using wsdl to java. However I am not sure how to Basic authentication. The documentation which tells me the details also says that I user name and pwd should be encoded using Base64.
The authentication method used is HTTP Basic . The user name and
password will need to be encoded in a base64 format – UTF8 character
set.
Example: Username:Password = “VXNlcm5hbWU6UGFzc3dvcmQ=”
BTW I have tried this wsdl in SOAP UI and and I am getting correct response but some how my java code won't work
Now Here is the wsdl
<?xml version="1.0" encoding="UTF-8"?>
<definitions targetNamespace="urn:OTSB2B" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="urn:OTSB2B" xmlns:intf="urn:OTSB2B" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<schema targetNamespace="urn:OTSB2B" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:urn="urn:OTSB2B">
<simpleType name="tn">
<restriction base="string">
<length value="10"/>
</restriction>
</simpleType>
<simpleType name="prov">
<restriction base="string">
<length value="2"/>
<enumeration value="on"/>
<enumeration value="qc"/>
</restriction>
</simpleType>
<element name="getPresaleByTN">
<complexType>
<sequence>
<element name="tn" type="urn:tn"/>
<element name="prov" type="urn:prov"/>
</sequence>
</complexType>
</element>
<element name="getPresaleByTNReturn" type="xsd:string"/>
<element name="isAlive"/>
<element name="isAliveReturn" type="xsd:boolean"/>
</schema>
</wsdl:types>
<message name="isAliveRequest">
<part element="impl:isAlive" name="isAlive"/>
</message>
<message name="getPresaleByTNRequest">
<part element="impl:getPresaleByTN" name="getPresaleByTN"/>
</message>
<message name="isAliveResponse">
<part element="impl:isAliveReturn" name="isAliveReturn"/>
</message>
<message name="getPresaleByTNResponse">
<part element="impl:getPresaleByTNReturn" name="getPresaleByTNReturn"/>
</message>
<portType name="GetPresaleByTN">
<operation name="getPresaleByTN">
<input message="impl:getPresaleByTNRequest" name="getPresaleByTNRequest"/>
<output message="impl:getPresaleByTNResponse" name="getPresaleByTNResponse"/>
</operation>
<operation name="isAlive">
<input message="impl:isAliveRequest" name="isAliveRequest"/>
<output message="impl:isAliveResponse" name="isAliveResponse"/>
</operation>
</portType>
<binding name="DominoSoapBinding" type="impl:GetPresaleByTN">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="getPresaleByTN">
<wsdlsoap:operation soapAction=""/>
<input name="getPresaleByTNRequest">
<wsdlsoap:body use="literal"/>
</input>
<output name="getPresaleByTNResponse">
<wsdlsoap:body use="literal"/>
</output>
</operation>
<operation name="isAlive">
<wsdlsoap:operation soapAction=""/>
<input name="isAliveRequest">
<wsdlsoap:body use="literal"/>
</input>
<output name="isAliveResponse">
<wsdlsoap:body use="literal"/>
</output>
</operation>
</binding>
<service name="GetPresaleByTNService">
<port binding="impl:DominoSoapBinding" name="Domino">
<wsdlsoap:address location="https://b2b.ivv.bell.ca/ots-qualification-service-tn"/>
</port>
</service>
</definitions>
I have tried this:
GetPresaleByTNServiceStub stub = new GetPresaleByTNServiceStub();
ServiceClient client = stub._getServiceClient();
client.addStringHeader(new QName("userName"), "XXX");
client.addStringHeader(new QName("password"), "YYYYYYYY");
GetPresaleByTNServiceStub.GetPresaleByTN request = new GetPresaleByTN();
Tn tn = new Tn();
tn.setTn("4164390001");
request.setTn(tn);
request.setProv(Prov.on);
GetPresaleByTNReturn response = stub.getPresaleByTN(request);
System.out.println(response.getGetPresaleByTNReturn());
This gives me following error:
org.apache.axis2.AxisFault: Failed to add string header, you have to
have namespaceURI for the QName at
org.apache.axis2.client.ServiceClient.addStringHeader(ServiceClient.java:434)
at com.dinesh.bellAxis.App.main(App.java:30)
Then I tried this
GetPresaleByTNServiceStub stub = new GetPresaleByTNServiceStub();
ServiceClient client = stub._getServiceClient();
HttpTransportProperties.Authenticator basicAuth = new HttpTransportProperties.Authenticator();
basicAuth.setUsername("XXX");
basicAuth.setPassword("CCCCC");
basicAuth.setPreemptiveAuthentication(true);
stub._getServiceClient().getOptions().setProperty(HTTPConstants.AUTHENTICATE, basicAuth);
GetPresaleByTNServiceStub.GetPresaleByTN request = new GetPresaleByTN();
Tn tn = new Tn();
tn.setTn("4164390001");
request.setTn(tn);
request.setProv(Prov.on);
GetPresaleByTNReturn response = stub.getPresaleByTN(request);
System.out.println(response.getGetPresaleByTNReturn());
This gives me the following error:
org.apache.axis2.AxisFault: Transport level information does not match
with SOAP Message namespace URI at
org.apache.axis2.AxisFault.makeFault(AxisFault.java:430) at
org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.java:90)
at
org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:353)
at
org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:416)
at
org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:228)
at
org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)
at
com.acn.client.GetPresaleByTNServiceStub.getPresaleByTN(GetPresaleByTNServiceStub.java:460)
Next I tried this: which I think is incorrect as it WS Security and not basic auth but what the heck I exhausted all my options
GetPresaleByTNServiceStub stub = new GetPresaleByTNServiceStub();
ServiceClient client = stub._getServiceClient();
OMFactory omFactory = OMAbstractFactory.getOMFactory();
OMElement omSecurityElement = omFactory.createOMElement(new QName( "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", "wsse"), null);
OMElement omusertoken = omFactory.createOMElement(new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "UsernameToken", "wsu"), null);
OMElement omuserName = omFactory.createOMElement(new QName("", "Username", "wsse"), null);
omuserName.setText("XXXX");
OMElement omPassword = omFactory.createOMElement(new QName("", "Password", "wsse"), null);
omPassword.addAttribute("Type","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText",null );
omPassword.setText("YYYYYYY");
omusertoken.addChild(omuserName);
omusertoken.addChild(omPassword);
omSecurityElement.addChild(omusertoken);
stub._getServiceClient().addHeader(omSecurityElement);
GetPresaleByTNServiceStub.GetPresaleByTN request = new GetPresaleByTN();
Tn tn = new Tn();
tn.setTn("4164390001");
request.setTn(tn);
request.setProv(Prov.on);
GetPresaleByTNReturn response = stub.getPresaleByTN(request);
System.out.println(response.getGetPresaleByTNReturn());
This gives the following error:
Exception in thread "main" java.lang.IllegalArgumentException: Cannot
create a prefixed element with an empty namespace name at
org.apache.axiom.om.impl.llom.OMElementImpl.handleNamespace(OMElementImpl.java:186)
at
org.apache.axiom.om.impl.llom.OMElementImpl.(OMElementImpl.java:161)
at
org.apache.axiom.om.impl.llom.factory.OMLinkedListImplFactory.createOMElement(OMLinkedListImplFactory.java:126)
at com.dinesh.bellAxis.App2.main(App2.java:37)
I am not sure what to do next and have checked all the documentation on Apache Axis2 and googled all over the place but could get the code to work.
Any suggestions
Code fragments 1 and 3 don't work because they attempt to create a message that is invalid with respect to SOAP (fragment 1) or XML (fragment 3). Anyway, they attempt to add SOAP headers to the message, which is not what basic auth is about.
Code fragment 2 looks correct. From the stack trace of the exception (more precisely the presence of the handleResponse method) you can see that there is an issue with the response. The error message likely indicates that the content type of the response doesn't match the SOAP version actually used in the response. This means that there is a problem with the service, not with the client.
I found the answer after a lot of trial and error and going over SAAj tutorial on Oracle website.
I able to do Basic authentication using this
String authorization = new sun.misc.BASE64Encoder().encode((“myUserName”+”:”+”myPassword”).getBytes());
headers.addHeader(“Authorization”, “Basic ” + authorization);
Here's the complete tutorial - http://www.javahabit.com/2014/10/17/quick-tutorial-saaj-api/