sorry for my English.
I am new to web services.
I have axis web service:
<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
...
<service name="ServerPt" provider="java:RPC" style="wrapped" use="literal">
...
<operation name="getStop" qname="operNS:getStop" xmlns:operNS="urn:StopServer" returnQName="return" returnType="rtns:Stop" xmlns:rtns="urn:StopServer" >
<parameter qname="id" type="tns:long" xmlns:tns="http://www.w3.org/2001/XMLSchema"/>
</operation>
...
<parameter name="allowedMethods" value="... getStop ..."/>
...
<typeMapping
xmlns:ns="urn:StopServer"
qname="ns:Stop"
type="java:net.fist.st.stops.soap.server.Stop"
serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
/>
...
</service>
...
</deployment>
And I wand access to this service from java client. Trying this:
public static void main(String[] args)
{
try
{
String endpoint = "http://192.168.0.1:28080/ws/services/ServerPt";
Service s = new Service();
Call c = (Call) s.createCall();
c.setTargetEndpointAddress(endpoint);
c.addParameter("id",org.apache.axis.Constants.XSD_LONG,javax.xml.rpc.ParameterMode.IN);
c.setReturnType(new QName("urn:StopServer", "rtns:Stop"), Stop.class);
c.registerTypeMapping(Stop.class, new QName("urn:StopServer", "rtns:Stop"), new BeanSerializerFactory(Stop.class, new QName("urn:StopServer", "rtns:Stop")), new BeanDeserializerFactory(Stop.class, new QName("urn:StopServer", "rtns:Stop")));
c.setOperation("getStop");
Stop st = (Stop)c.invoke( new Object[] { new Long(295) } );
System.out.println(st.getCode().toString());
} catch(Exception e)
{
e.printStackTrace();
}
}
But thrown exception:
org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.
Server receive request, and in log files I see:
= Elapsed: 117 milliseconds
= In message: <?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><getStop xmlns=""><arg0 xsi:type="xsd:long">295</arg0></getStop></soapenv:Body></soapenv:Envelope>
= Out message: <?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><getStopResponse xmlns=""><return><id>295</id><name>Lupe</name><country>GB</country><district> </district><code>250</code><codeInf>094811</codeInf><railCode>25</railCode></return></getStopResponse></soapenv:Body></soapenv:Envelope>
=======================================================
Please help.
IMHO you will be better off generating a client using wsdl2java instead of writing your own fancy code to consume a web service.
Related
I have searched for this in Internet but unable to find a answer.
I am new to SOAP services, If I am wrong at any point please correct me. I was trying to generate Java classes from wsdl using command line tool ** JAX-WS RI wsimport**. I was able to generate all Request and Response classes.
The ObjectFactory.java generated from wsdl was missing most of the methods.
employee.wsdl.jaxb.bnd.xml
<jaxb:bindings version="2.0"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb/xjc">
<jaxb:bindings>
<jaxb:globalBindings generateElementProperty="false">
<xjc:serializable>
</jaxb:globalBindings>
</jaxb:bindings>
</jaxb:bindings>
employee.wsdl.bnd.xml
<jaxws:bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://java.sun.com/xml/ns/jaxws"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
wsdlLocation="../sp.wsdl">
<jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle>
</jaxws:bindings>
In jaxb.bnd.xml
While trying with <jaxb:globalBindings generateElementProperty="true"> Its able to generate all of the factory methods. But it was using JAXBElement<> wrapper for primititve data types like String,int,Long
While trying with <jaxb:globalBindings generateElementProperty="fasle"> Its able to generate the class without JAXBElement<> wrapper, but missing most of the factory methods.
cmd: wsimport META-INF/wsdl/employee.wsdl -keep -b META-INF/wsdl/bindings/employee.bnd.xml -b META-INF/wsdl/bindings/employee.jaxb.bnd.xml -wsdllocation META-INF/wsdl/employee.wsdl
Sample ObjectFactory.java
package xyz;
#XmlRegistry
class ObjectFactory {
private final static Qname _EmpDetailsSpecialEmpDetail_QNAME = new QName("", "scheduleEmp");
#XmlElementDecl(namespce = "", name="specialEmployee", scope= EmpDetails.class)
public SpecialEmpDetail EmpDetailsSpecialEmployee(SpecialEmpDetail value) {
return new SpecialEmpDetail(_EmpDetailsSpecialEmpDetail_QNAME, SpecialEmpDetail.class, EmpDetail.class, value);
}
EmpDetail.java
public class EmpDetail implements Serializable {
#XmlElementRef(name= "specialEmployee", required=false)
protected SpecialEmpDetail specialEmployee;
public SpcialEmpDetail getSpecialEmployee() {
return specialEmployee;
}
public SpcialEmpDetail setSpecialEmployee(SpcialEmpDetail value) {
this.specialEmployee = value;
}
}
SpecialEmpDetail.java
public class SpecialEmpDetail {
//local var
//getter and setter
.....
}
employee.wsdl
<?xml version="1.0" encoding="UTF-8">
<definitions name="psp"
targetNamespace="http://www.namespace.com/employee.wsdl"
.....
/>
<types>
<schmea targerNamespace = "http://www.namespace.com/employee.wsdl"
xmlns:SOAP-ENV = "http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi = "http://www.w3.org/2003/05/XMLSchema-instance"
xmlns:xsd = "http://www.w3.org/2001/XMLSchema"
xmlns:emp = "http://www.namespace.com/employee/employee.xsd1"
<import namespace="http://www.namespace.com/employee.xsd1"/>
<import namespace="http://www.w3.org/2003/05/soap-encoding"/>
</schmea>
<schmea targerNamespace = "http://www.namespace.com/employee.xsd1"
xmlns:SOAP-ENV = "http://www.w3.org/2003/05/soap-envelope"
xmlns:xsi = "http://www.w3.org/2003/05/XMLSchema-instance"
xmlns:xsd = "http://www.w3.org/2001/XMLSchema"
xmlns:emp = "http://www.namespace.com/employee/employee.xsd1"
<import namespace="http://www.namespace.com/employee.wsdl"/>
<import namespace="http://www.w3.org/2003/05/soap-encoding"/>
<simpleType name="empName">
<restrictions base="xsd:string">
<minLength value="1"/>
<maxLength value="30"/>
</restrictions>
<simpleType name="EmpID">
<restrictions base="xsd:string">
<minLength value="0"/>
<maxLength value="25"/>
</restrictions>
</simpleType>
<complexType name="">
<sequence>
<element name="specialEmployee" type="emp:SpecialEmpDetail minOccurs="0" maxOccurs="1" />
</sequence>
</complexType>
.....
.........
</schema>
</types>
Here is the sample wsdl and java. I can able to generate SpecialEmpDetail.java & EmpDetail.java The ObjectFctory.java should create the mentioned function, but its failed to do so.... Using JAXBElement<> wrapper I can able to generate all functions but the problem here is its a complextType data so wrapping is fine, But String also wrapped this is not expected.
What may be problem?? How can I resolve it??
Thanks in Advance!
I am having trouble getting WCF binding to work with Blackboard Java Web Services API.
(Simple answer would be if anyone has got this working could you
please post a working binding for WCF to Blackboard)
I have spent hours trying different configurations and custom coded bindings.
Some unsuccessful attempts:
calling-a-ws-security-java-web-service-with-c-sharp-client
wcf-client-with-ws-security 12-common-wcf-interop-confusions
configure-wcf-for-ws-security-with-username-over-https
wcf-client-connecting-to-java-soap-web-service-using-ws-security
ClearUsernameBinding
There are many more to do with JAVA and WS-Security with WCF but I wont go on.
It seems that every time I get one thing working another breaks. Now I feel like I am going around in circles and just making myself even more confused.
As my first test what I am trying to do is simple Initialize the Context object and Login using an Admin test user account with a WCF proxy.
Blackboard Doc ContextWS
To make sure that all of this worked I first I downloaded the sample code for .Net WSE 2.0 and tested that, it worked perfectly.
Now when I use WCF and binding I cannot get this same behaviour.
First the Successful exchange with very old WSE 2.0
===================================
WSE 2.0 ContextWS Initialization
<?xml version="1.0" encoding="utf-8"?>
<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" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<wsa:Action>initialize</wsa:Action>
<wsa:MessageID>uuid:b975e989-a4ce-4e1e-abd6-500945346c40</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>https://Blackboard.Server.Name/webapps/ws/services/Context.WS</wsa:To>
<wsse:Security soap:mustUnderstand="1">
<wsu:Timestamp wsu:Id="Timestamp-47d0d017-4fd1-46c2-b1b4-2431402cf847">
<wsu:Created>2015-07-16T04:58:02Z</wsu:Created>
<wsu:Expires>2015-07-16T05:03:02Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-1b71e23a-2d84-40a5-9509-b75902ec8b76">
<wsse:Username>session</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">nosession</wsse:Password>
<wsse:Nonce>lAW2qXrXZ1maNNkCEzlHGA==</wsse:Nonce>
<wsu:Created>2015-07-16T04:58:02Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body />
</soap:Envelope>
WSE 2.0 ContextWS Initialization Success Response
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:initializeResponse xmlns:ns="http://context.ws.blackboard">
<ns:return>c2762f357bbc42a4a88d33e4e42486b8</ns:return>
</ns:initializeResponse>
</soapenv:Body>
</soapenv:Envelope>
WSE 2.0 ContextWS Login Request
<?xml version="1.0" encoding="utf-8"?>
<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" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<wsa:Action>login</wsa:Action>
<wsa:MessageID>uuid:a823128b-efb4-49e1-87d9-fd35167f0bfc</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>https://Blackboard.Server.Name/webapps/ws/services/Context.WS</wsa:To>
<wsse:Security soap:mustUnderstand="1">
<wsu:Timestamp wsu:Id="Timestamp-c38daf19-6b39-4391-a3f8-bcc030064a3e">
<wsu:Created>2015-07-16T04:58:15Z</wsu:Created>
<wsu:Expires>2015-07-16T05:03:15Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="SecurityToken-65948746-e616-436a-85f4-d2e1023e39be">
<wsse:Username>session</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">c2762f357bbc42a4a88d33e4e42486b8</wsse:Password>
<wsse:Nonce>T0xs8aiaiODMK3sfKgDQtg==</wsse:Nonce>
<wsu:Created>2015-07-16T04:58:15Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
<login xmlns="http://context.ws.blackboard">
<userid>test_admin</userid>
<password>TestPassword</password>
<clientVendorId>TestClient</clientVendorId>
<clientProgramId>TestPOC</clientProgramId>
<loginExtraInfo xsi:nil="true" />
<expectedLifeSeconds>10000000</expectedLifeSeconds>
</login>
</soap:Body>
</soap:Envelope>
WSE 2.0 ContextWS Login Success Response
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:loginResponse xmlns:ns="http://context.ws.blackboard">
<ns:return>true</ns:return>
</ns:loginResponse>
</soapenv:Body>
</soapenv:Envelope>
===================================
So I know that this works to our environment and I know the user can login.
Using WCF I am able to get the Initialization working but then it looses the session. It does not put the Returned Session ID into the Password field for the next message. I have tried to do this manually of course; but I get an error stating the Password field is read only.
Now for my WCF Configuration and code that has gotten me closest to the above communication.
WCF App.Config Binding
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</system.serviceModel>
<bindings>
<customBinding>
<binding name="WCFSoapInteropJavaWS" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" >
<textMessageEncoding messageVersion="Soap11" writeEncoding="utf-8" />
<security authenticationMode="UserNameOverTransport" enableUnsecuredResponse="true" allowSerializedSigningTokenOnReply="true"
messageSecurityVersion="WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10"
includeTimestamp="true" allowInsecureTransport="true" canRenewSecurityContextToken="false" >
</security>
<httpsTransport authenticationScheme="Anonymous" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint
address="https://Blackboard.Server.Name:443/webapps/ws/services/Context.WS"
binding="customBinding" bindingConfiguration="WCFSoapInteropJavaWS"
contract="ContextWS.ContextWSPortType" name="Context.WCFSoapInteropJavaWS" />
</client>
</system.serviceModel>
</configuration>
WCF C# code
public bool testWrapper(String userId, String userPassword){
try
{
context = new ContextWrapper("Context.WCFSoapInteropJavaWS");
context.ClientCredentials.UserName.UserName = "session";
context.ClientCredentials.UserName.Password = "nosession";
context.initialize();
//context.ClientCredentials.UserName.Password = "886d935527944f94a3526288e39a555e"; // SessionGUID_HERE Throws a Read Only Error for Pasword
bool retval = context.login(userId, userPassword, vendorId, programId, null, expectedLife);
return retval;
}
catch (System.Exception e)
{
lastError = e;
return false;
}
}
This is what the SOAP communication looks like.
WCF ContextWS Initialization Request
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo+FmveflwUtMgSATRu3Ht9EAAAAAmYVJsX+bhUeYcTDsFqFktkqe8xmMiA1MpXouaouXgJwACQAA</VsDebuggerCausalityData>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2015-07-16T07:15:05.109Z</u:Created>
<u:Expires>2015-07-16T07:20:05.109Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-1237f56c-7c68-4d40-a756-7ff2c19a3235-1">
<o:Username>session</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">nosession</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"/>
</s:Envelope>
WCF ContextWS Initialization Success Response
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<ns:initializeResponse xmlns:ns="http://context.ws.blackboard">
<ns:return>886d935527944f94a3526288e39a555e</ns:return>
</ns:initializeResponse>
</soapenv:Body>
</soapenv:Envelope>
WCF ContextWS Login Request
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<VsDebuggerCausalityData xmlns="http://schemas.microsoft.com/vstudio/diagnostics/servicemodelsink">uIDPo+JmveflwUtMgSATRu3Ht9EAAAAAmYVJsX+bhUeYcTDsFqFktkqe8xmMiA1MpXouaouXgJwACQAA</VsDebuggerCausalityData>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2015-07-16T07:15:14.033Z</u:Created>
<u:Expires>2015-07-16T07:20:14.033Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="uuid-1237f56c-7c68-4d40-a756-7ff2c19a3235-1">
<o:Username>session</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">nosession</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<login xmlns="http://context.ws.blackboard">
<userid>Test_admin</userid>
<password>TestPassword</password>
<clientVendorId>TestClient</clientVendorId>
<clientProgramId>TestPOC</clientProgramId>
<loginExtraInfo xsi:nil="true"/>
<expectedLifeSeconds>10000000</expectedLifeSeconds>
</login>
</s:Body>
</s:Envelope>
WCF ContextWS Login Failed Response
<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Body>
<soapenv:Fault>
<faultcode>soapenv:Server</faultcode>
<faultstring>[WSFW001]Invalid session</faultstring>
<detail />
</soapenv:Fault>
</soapenv:Body>
</soapenv:Envelope>
As you can see the session return id has not been added to the password field on the login request so there is a "Invalid Session:
It all seemed to be going so well.
In short if anyone knows how to achieve a binding from a WCF Client to the Blackboard Java Webservice API and example would be fantastic. Other wise I am hoping that someone else that knows more about WCF Bindings to Java than I do might be able to take a look at the above see where I am going wrong.
Any help anyone can give me to get this working would be much appreciated so thanks. I really am hoping it is just something silly that I am missing.
Sorry for such a long detailed question.
Thanks to heaps of reading and some useful samples I was able to get this working. Blackboard with WCF.
Thanks go to both:
Ajadex Lopez
http://www.isyourcode.com/2010/08/attaching-oasis-username-tokens-headers.html
Johnny Lockhart
"Incoming message does not contain required Security header"
BB is buggie so you might do best to search the forum for WCF to find the post
Sample class
using System;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel;
using System.Xml;
using System.Security.Cryptography;
using System.Text;
namespace BBWcfWrapper
{
/// <summary>
/// Coupled with the additional classes below, allows for injecting the WS-Security header into a WCF Service call without requiring SSL on the server.
/// </summary>
/// <remarks>http://isyourcode.blogspot.com/2010/08/attaching-oasis-username-tokens-headers.html</remarks>
public class BBWSSecurityBehavior : IEndpointBehavior
{
public MessageInspector MessageInspector { get; set; }
public BBWSSecurityBehavior(MessageInspector messageInspector)
{
MessageInspector = messageInspector;
}
public void Validate(ServiceEndpoint endpoint)
{ }
public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
{ }
public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
if (this.MessageInspector == null) throw new InvalidOperationException("Caller must supply ClientInspector.");
clientRuntime.MessageInspectors.Add(MessageInspector);
}
}
public class MessageInspector : IClientMessageInspector
{
public MessageHeader[] Headers { get; set; }
public MessageInspector(params MessageHeader[] headers)
{
Headers = headers;
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
if (Headers != null)
{
for (int i = Headers.Length - 1; i >= 0; i--)
{
request.Headers.Insert(0, Headers[i]);
}
}
return request;
}
public void AfterReceiveReply(ref Message reply, object correlationState)
{
}
}
public class SecurityHeader : MessageHeader
{
public string SystemUser { get; set; }
public string SystemPassword { get; set; }
public SecurityHeader(string systemUser, string systemPassword)
{
SystemUser = systemUser;
SystemPassword = systemPassword;
}
public override string Name
{
get { return "Security"; }
}
public override string Namespace
{
get { return "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; }
}
protected override void OnWriteStartHeader(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
writer.WriteStartElement("wsse", Name, Namespace);
writer.WriteXmlnsAttribute("wsse", Namespace);
writer.WriteAttributeString("soap", "mustUnderstand", Namespace, "1");
}
protected override void OnWriteHeaderContents(XmlDictionaryWriter writer, MessageVersion messageVersion)
{
WriteHeader(writer);
}
private void WriteHeader(XmlDictionaryWriter writer)
{
var createDate = DateTime.Now;
//Start Parent Elements
writer.WriteStartElement("wsu","Timestamp","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
writer.WriteAttributeString("wsu","id","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd","Timestamp-6557466");
#region Start Child Elements
writer.WriteStartElement("wsu", "Created", XmlConvert.ToString(createDate, "yyyy-MM-ddTHH:mm:sszzzzzz"));
writer.WriteEndElement(); //End Created
writer.WriteStartElement("wsu", "Expires", XmlConvert.ToString(createDate.AddDays(1), "yyyy-MM-ddTHH:mm:sszzzzzz"));
writer.WriteEndElement(); //End Expires
#endregion
writer.WriteEndElement(); //End Timestamp
//Start Parent Elements
writer.WriteStartElement("wsse", "UsernameToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
writer.WriteXmlnsAttribute("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
#region Start Child Elements
writer.WriteStartElement("wsse", "Username", null);
writer.WriteString(SystemUser);
writer.WriteEndElement();//End Username
writer.WriteStartElement("wsse", "Password", null);
writer.WriteAttributeString("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
writer.WriteString(SystemPassword);
writer.WriteEndElement();//End Password
// unique Nonce value - encode with SHA-1 for 'randomness'
// in theory the nonce could just be the GUID by itself
// This is used to stop Replay attacks
writer.WriteStartElement("wsse", "Nonce", null);
writer.WriteString(GetSHA1String(Guid.NewGuid().ToString()));
writer.WriteEndElement();//Nonce
writer.WriteStartElement("wsu", "Created", null);
writer.WriteString(XmlConvert.ToString(createDate, "yyyy-MM-ddTHH:mm:sszzzzzz"));
writer.WriteEndElement(); //End Created
#endregion
writer.WriteEndElement();//End UsernameToken
writer.Flush();
}
protected string GetSHA1String(string phrase)
{
SHA1CryptoServiceProvider sha1Hasher = new SHA1CryptoServiceProvider();
byte[] hashedDataBytes = sha1Hasher.ComputeHash(Encoding.UTF8.GetBytes(phrase));
return Convert.ToBase64String(hashedDataBytes);
}
}
}
Example Use
calendar = new CalendarWrapper("Calendar.BB_WSSecurity_Binding");
//This adds a custom security Headder for WCF and Java WS-Security Interop
calendar.Endpoint.Behaviors.Add(new BBWSSecurityBehavior(new MessageInspector(BbWsAuth.SecurityHeader)));
calendar.initializeCalendarWS(false);
Simple Wrapper class
public class CalendarWrapper : CalendarWSPortTypeClient
{
public CalendarWrapper() : base() { }
public CalendarWrapper(string endpointConfigurationName) : base(endpointConfigurationName) { }
public CalendarWrapper(Binding binding, EndpointAddress remoteAddress) : base(binding, remoteAddress) { }
}
Config
<bindings>
<basicHttpsBinding>
<binding name="BB_WSSecurity_Binding" messageEncoding="Text" textEncoding="utf-8" maxReceivedMessageSize="4000000" >
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</binding>
</basicHttpsBinding>
</bindings>
<client>
<endpoint address="https://xxxxxxxxxx/webapps/ws/services/Calendar.WS"
binding="basicHttpsBinding" bindingConfiguration="BB_WSSecurity_Binding"
contract="CalendarWS.CalendarWSPortType" name="Calendar.BB_WSSecurity_Binding" />
I have a flow with a custon filter that works(with an echo) but if I try tu use a twitter cloud connector i get this error
ERROR 2015-04-04 19:09:02,451 [[CopyTrabajosd2].trabajosdFlow.stage1.02] org.mule.retry.notifiers.ConnectNotifier: Failed to connect/reconnect: Work Descriptor. Root Exception was: Response code 403 mapped as failure. Message payload is of type: BufferInputStream. Type: class org.mule.module.http.internal.request.ResponseValidatorException
ERROR 2015-04-04 19:09:02,458 [[CopyTrabajosd2].trabajosdFlow.stage1.02] org.mule.exception.CatchMessagingExceptionStrategy:
********************************************************************************
Message : Response code 403 mapped as failure. Message payload is of type: BufferInputStream
Code : MULE_ERROR--2
--------------------------------------------------------------------------------
Exception stack is:
1. Response code 403 mapped as failure. Message payload is of type: BufferInputStream (org.mule.module.http.internal.request.ResponseValidatorException)
org.mule.module.http.internal.request.SuccessStatusCodeValidator:37 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/module/http/internal/request/ResponseValidatorException.html)
--------------------------------------------------------------------------------
Root Exception stack trace:
org.mule.module.http.internal.request.ResponseValidatorException: Response code 403 mapped as failure. Message payload is of type: BufferInputStream
at org.mule.module.http.internal.request.SuccessStatusCodeValidator.validate(SuccessStatusCodeValidator.java:37)
at org.mule.module.http.internal.request.DefaultHttpRequester.innerProcess(DefaultHttpRequester.java:202)
at org.mule.module.http.internal.request.DefaultHttpRequester.process(DefaultHttpRequester.java:166)
+ 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)
********************************************************************************
I think that the clout connector is not receiving the input type that it needs but I'm not sure ,any help?
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:twitter="http://www.mulesoft.org/schema/mule/twitter" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:json="http://www.mulesoft.org/schema/mule/json" xmlns:smtp="http://www.mulesoft.org/schema/mule/smtp"
xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="EE-3.6.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/smtp http://www.mulesoft.org/schema/mule/smtp/current/mule-smtp.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/json http://www.mulesoft.org/schema/mule/json/current/mule-json.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/twitter http://www.mulesoft.org/schema/mule/twitter/current/mule-twitter.xsd">
<smtp:gmail-connector name="gmail" doc:name="Gmail"/>
<http:request-config name="HTTP_Request_Configuration" host="api.openweathermap.org" port="80" basePath="data/2.5/forecast/daily?q=San Fernando,es&lang=es&units=metric&cnt=2&mode=json" doc:name="HTTP Request Configuration"/>
<spring:beans>
<spring:bean id="transformador" name="Bean" class="com.trabajosd.Transformador"/>
</spring:beans>
<twitter:config name="Twitter__Configuration" accessKey="3006010565-rUz6h4xnNoHO2juxGYQEK5jcM5DvSpxv7P3hv07" accessSecret="KxcqDQEo6JbHHR2S10lFN5luxXLEJauNhiBdZIeY7tUXO" consumerKey="LBxBQUYhbAFb5PeBtR7Jg4Evo" consumerSecret="AdD8lJYRS1OadJsn2BXhEbnhdcUNc1t3uM9pnOGH7eNfE2JxZu" doc:name="Twitter: Configuration"/>
<flow name="trabajosdFlow">
<poll doc:name="Poll">
<fixed-frequency-scheduler frequency="10000"/>
<http:request config-ref="HTTP_Request_Configuration" path="/" method="GET" doc:name="HTTP"/>
</poll>
<logger level="INFO" doc:name="Logger"/>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<json:json-to-object-transformer doc:name="JSON to Object"/>
<custom-filter class="com.trabajosd.Filtro" doc:name="Custom"/>
<twitter:update-status config-ref="Twitter__Configuration" status="Predicción de lluvia para hoy(Prueba Mule)" doc:name="Twitter"/>
<catch-exception-strategy doc:name="Catch Exception Strategy"/>
</flow>
<catch-exception-strategy name="trabajosdCatch_Exception_Strategy">
<logger level="INFO" doc:name="Logger"/>
</catch-exception-strategy>
</mule>
And the custon filter class
package com.trabajosd;
import org.json.JSONArray;
import org.json.JSONObject;
import org.mule.api.MuleMessage;
import org.mule.api.routing.filter.Filter;
public class Filtro implements Filter{
#Override
public boolean accept(MuleMessage message) {
try {
String json=message.getPayloadAsString();
JSONObject obj = new JSONObject(json);
JSONArray lista = obj.getJSONArray("list");
JSONObject elemento0 =lista.getJSONObject(0);
JSONArray clima = elemento0.getJSONArray("weather");
JSONObject prediccion = clima.getJSONObject(0);
return prediccion.getString("main").equalsIgnoreCase("Clouds");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
}
It seems that there is an issue with WWW-authenticate header header in Mule 3.6.x.
The error usually is "401 response received, but no WWW-Authenticate header was present". Not sure why it is http response 403 in your case.
I tried a basic twitter flow and it works on Mule 3.5 but not 3.6.
The reported issues are:
https://www.mulesoft.org/jira/browse/MULE-8282
https://www.mulesoft.org/jira/browse/MULE-8127
https://www.mulesoft.org/jira/browse/MULE-8249
I searched google, but i cant find a way to do this. I have a SOAP webservice built in netbeans with JAX-WS . Gerated wsdl cannot be accessed by my java client code. Is the way i am trying to access is wrong? someone help..
my web service code
#WebService(serviceName = "HolaMundo")
public class HolaMundo {
#WebMethod(operationName = "hello")
public String hello(#WebParam(name = "name") String txt) {
return "Hello " + txt + " !";
}
}
generated wsdl
<!--
Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2-hudson-740-.
-->
<!--
Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2-hudson-740-.
-->
<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://publicar.ws.org.mx/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://publicar.ws.org.mx/" name="HolaMundo">
<types>
<xsd:schema>
<xsd:import namespace="http://publicar.ws.org.mx/" schemaLocation="http://localhost:8084/HolaMundo/HolaMundo?xsd=1"/>
</xsd:schema>
</types>
<message name="hello">
<part name="parameters" element="tns:hello"/>
</message>
<message name="helloResponse">
<part name="parameters" element="tns:helloResponse"/>
</message>
<portType name="HolaMundo">
<operation name="hello">
<input wsam:Action="http://publicar.ws.org.mx/HolaMundo/helloRequest" message="tns:hello"/>
<output wsam:Action="http://publicar.ws.org.mx/HolaMundo/helloResponse" message="tns:helloResponse"/>
</operation>
</portType>
<binding name="HolaMundoPortBinding" type="tns:HolaMundo">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="hello">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="HolaMundo">
<port name="HolaMundoPort" binding="tns:HolaMundoPortBinding">
<soap:address location="http://localhost:8084/HolaMundo/HolaMundo"/>
</port>
</service>
</definitions>
Java client code
public class cliente {
public cliente() {
}
public static String consumir(Object[] parametros){
String regresar = null;
Service service = null;
Call call = null;
String endpoint = null;
try {
endpoint = "http://localhost:8084/HolaMundo/HolaMundo";
service = new Service();
call = (Call) service.createCall();
call.setTargetEndpointAddress(new java.net.URL(endpoint));
call.setOperationName("hello");
regresar=String.valueOf(call.invoke(parametros));
}// try
catch (Exception e) {
e.printStackTrace();
}// catch
finally {
return regresar;
}// finally
}
public static void main(String[] args) {
try {
String parametro = "José";
String respuesta = consumir(new Object[]{parametro});
System.out.println("respuesta: --->" + respuesta);
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
but i am getting the error
AxisFault
faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Client
faultSubcode:
faultString: Cannot find dispatch method for {}hello
faultActor:
faultNode:
faultDetail:
{http://xml.apache.org/axis/}stackTrace:Cannot find dispatch method for {}hello
help me. thanks
I have to develop several WS in Java. Cause I have no previous experience with this, I started with a simple example. Here the WS:
#WebService
public interface DataExchangeWebService {
public int doubleIt(int numberToDouble);
}
#WebService(targetNamespace = "http://www.example.com/ws/DataExchange",
portName = "DataExchangePort",
serviceName = "DataExchangeService",
endpointInterface = "xyz.DataExchangeWebService")
public class DataExchangeWebServiceImpl implements DataExchangeWebService {
#Override
public int doubleIt(int numberToDouble) {
return numberToDouble * 2;
}
}
Now I would like to test this Service only via JUnit. I found this blog entry, which builds the starting point for my test case. To keep it simple, I used the Java Endpoint class.
protected static URL wsdlURL;
protected static QName serviceName;
protected static QName portName;
protected static Endpoint endpoint;
protected static String address;
static {
serviceName = new QName("http://www.example.com/ws/DataExchange", "DataExchangeService");
portName = new QName("http://www.example.com/ws/DataExchange", "DataExchangePort");
}
#BeforeClass
public static void setUp() throws MalformedURLException {
address = "http://localhost:9000/ws/DataExchange";
wsdlURL = new URL(address + "?wsdl");
endpoint = Endpoint.publish(address, new DataExchangeWebServiceImpl());
}
#AfterClass
public static void tearDown() {
endpoint.stop();
}
This publishes the WS and generates the following WSDL:
<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is
JAX-WS RI 2.1.6 in JDK 6. -->
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is
JAX-WS RI 2.1.6 in JDK 6. -->
<definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://www.example.com/ws/DataExchange" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://www.example.com/ws/DataExchange"
name="DataExchangeService">
<import namespace="http://dataexchange.sys.cs.iface.service.appserver.xyz/"
location="http://localhost:9000/ws/DataExchange?wsdl=1" />
<binding xmlns:ns1="http://dataexchange.sys.cs.iface.service.appserver.xyz/"
name="DataExchangePortBinding" type="ns1:DataExchangeWebService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
style="document" />
<operation name="doubleIt">
<soap:operation soapAction="" />
<input>
<soap:body use="literal" />
</input>
<output>
<soap:body use="literal" />
</output>
</operation>
</binding>
<service name="DataExchangeService">
<port name="DataExchangePort" binding="tns:DataExchangePortBinding">
<soap:address location="http://localhost:9000/ws/DataExchange" />
</port>
</service>
</definitions>
Now I have two test cases. The first one, uses the plain service to make the request:
public void raw_service() {
Service service = Service.create(wsdlURL, serviceName);
DataExchangeWebService dataExchangeWebService = service.getPort(portName, DataExchangeWebService.class);
int resp = dataExchangeWebService.doubleIt(10);
assertEquals(20, resp);
}
This one is working fine. The problematic is the second one. It uses a a SOAP message to make the request:
public void raw_service_with_full_soap_message() throws DOMException, SOAPException, IOException {
Service service = Service.create(wsdlURL, serviceName);
Dispatch<SOAPMessage> disp = service.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE);
InputStream is = getClass().getClassLoader().getResourceAsStream("fullSOAPMessage.xml");
SOAPMessage reqMsg = MessageFactory.newInstance().createMessage(null, is);
assertNotNull(reqMsg);
SOAPMessage response = disp.invoke(reqMsg);
assertEquals("Double-It not doubling zero correctly", "0", response.getSOAPBody().getTextContent().trim());
}
The fullSOAPMessage.xml looks as follows:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:doubleIt xmlns:ns2="http://www.example.com/ws/DataExchange">
<numberToDouble>0</numberToDouble>
</ns2:doubleIt>
</soap:Body>
</soap:Envelope>
JUnit fails with:
javax.xml.ws.soap.SOAPFaultException: Cannot find dispatch method for {http://www.example.com/ws/DataExchange}doubleIt
The research I have done so far only revealed, that this has something to do with conflicts between the target namespace of the WS and the SOAP message. But in my eyes thats not the case here.
Some ideas about how to solve this or whats going on?