Consuming a WCF service in a Java Client using wsHttpBinding - java

I'm trying to get a Java Client to communicate with a WCF wshttpbinding WebService. But I've been unsucesful so far. The call either hangs, or I get: “SOAPFaultException: The message could not be processed. This is most likely because the action 'http://tempuri.org/ISampleService/GetServiceName' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint's binding.”
My Web Service is just the default Visual Studio 2010 generated "WCF Service Library Template".
My java client is generated in netBeans 7.0.1 and stubs have been generated using new Other --> Web Services --> Web Service Client and I’m referencing a local WSDL.
I've tried adding WebServiceFeature wsAddressing = new AddressingFeature(true); in the stub generated but it just throws the exception above.
I see other people with similar problems; however, I don't see any true resolution. Any suggestions would be greatly appreciated.

It sounds like you have a soap formatting issue. The java client isn't generating soap XML that makes sense to the WCF service. To get an idea of what the soap XML the service is expecting use the WcfTestClient command line app to call the service. This app dynamically creates a service proxy in a WinForm app. In the app, call the service operation and click the XML tab (next to the Formatted tab at the bottom of the right pane). You'll see both the request & response soap in this tab.
Next, configure the WCF service for message tracing and call it from the java client to see the soap XML it is being sent. Now you can compare the two soap messages to see what is different. The java client will need be configured to generate the soap format the WCF is expecting.
The WCF team recently released some WCF interop bindings specifically for java. These may not apply to your specific situation but they're probably worth reviewing.

Related

Simulate Web Service when it's unavailable

Can somebody recommend the best way to simulate web service when it's unavailable. Is there a framework, able to record and notify the users when the web service is inaccessible ?
Thanks !
I've developed demos which have a failover in case of a 400 or 500 error code on the service response (due to lack of connectivity or firewalling on the customer side network). Basically, it has to be on the client code, though, where the logic parses the response and if it encounters unexpected/bad responses, has a default scenario to handle that situation.
It's not something I've done in production, but it does save some embarrassing situations in a skunkworks projects where your main application server is down or not responsive.
I saved the request of the client (soap request) in the database (byte array) , and saved the soap response also (if there is already a response). So, when the web service is unavailable, I search the last response existing in the database, which corresponds the request. If the remote service is not yet in operation, I used SoapUI API to generate a default response.
See also:
MockResponse

Google Calendar Push Notifications: Correct Domain Validation and Registration but Unable to receive notifications

I'm facing an issue with Google Calendar Push Notifications. First I'd like to explain my scenario.
I'm trying to develop a java application to be integrated in a platform that handles sensors and actuators. The goal of this application is to use Google Calendar APIs and Push Notifications to follow a certain kind of events. My first "architecture" that I chose is the following ( I'm open to suggestions and criticism given my young experience as developper ;-) :
A simple Tomcat Servlet which will be the final webhook for Google Servers (A);
A java class that implements a simple Server-Client Socket (B);
A java class that uses Google Calendar API and receive push messages through one of its methods (C);
The logic (maybe not so efficient) behind this structure is that Google Servers send notifications to my Tomcat webhook, which at the same time is the client of my Socket channel. When it receives pushes, it does its job and warns the Socket Server. The latter, thanks to a static object, invokes a method of C. This class will use Google APIs to check what's happened.
First and mandatory resource to study is: https://developers.google.com/google-apps/calendar/v3/push
I've been able to complete Step 1: Verify that you own the domain using Webmaster Tools and add correctly my domain for push notifications as indicated in Step 2: Register your domain These two steps lead me to my first question:
Does Google check whether the listed domains have valid SSL certificates during these two steps?
My domain is something like "domain.com" and the full URL to reach the webhook is hhttps://ab.domain.com/app/notifications. There is a very important note in Google documentation:
Note that the Google Calendar API will be able to send notifications to this >HTTPS address only if there is a valid SSL certificate installed on your web >server. Invalid certificates include:
Self-signed certificates.
Certificates signed by an untrusted source.
Certificates that have been revoked.
Certificates that have a subject that doesn't match the target
hostname.
First thing first, I've configured Tomcat to enable SSL and so HTTPS following the official documentation: tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html . Now I can access tomcat and my servlet through https.
The problem is that I can't receive "correctly" the push notifications. By using a browser plugin for simulating Http/Https request I can reach easily my Tomcat webhook and this one warns correctly my Java application. Therefore , since I can almost exclude problems about the Socket channel, I'm focusing on the communication between Google Servers and my Tomcat webhook.
I'm using Wireshark to see the incoming traffic from Google through the port 8443 (https for Tomcat). Obviously is encrypted, so I can't check a lot, but many packets are marked as PSH(push). However they seem to have a payload, which according to Google doc,they shouldn't because push notifications are just packets with headers info.
So my very first doubt is about the certificate. I don't have one, therefore I'm using this trial one from Verisign.com (which by the way is suggested in the Tomcat documentation for enabling SSL)
The very second doubt is about the validation and registration procedure. Even though I've managed to do it and Google is accepting the domain ab.domain.com/app/notifications as webhook, I don't have tools to prove that everything is correct.
I've found the following post in Stackoverflow: "Unable to receive push notification for Google calender", "Calendar push notification to java app engine backend servlet", "Google Calendar Push Notification watch command" I've already verified the differents answers and suggestions and nothing changed.
What am I missing ? Thanks a lot, I would be grateful for any tip, hint, answer, pointer :-)
If you're trying to debug a webhook, either for mechanics (i.e. proper setup on the sender side) or correctness (examining the post payload) try using RequestBin. If possible, register both a RequestBin URL along with your intended destination URL. RequestBin will give you full visibility of what the payload is, as well as give you assurances that you've set things up properly on the sender (Google) side.
You will need a valid SSL ceritificate. Self-signed is not allowed.

Manual Weblogic Basic Authentication

I have a Web Service (JAX-WS), a WSDL, a desktop application Client, and a Weblogic 12c server. I am trying to implement basic authentication between the Client->Web Service->Weblogic->Active Directory. I have been able to set everything up by putting the Username/Password in the header of the SOAP message when sending it from the Client to the Web Service.
Weblogic automatically pulls that header info and authenticates a user against Active Directory. Great. But the issues at hand are thse:
Should I not send credentials in the header at all, it doesn't authenticate but allows full access to anonymous users.
I need to send a proper error message and prevent anonymous usage.
Should I send invalid credentials it throws a socket read exception on the client.
I need to send back a proper error message; rather than having it bomb out on the client.
Should I send valid credentials but invalid authorization; I have setup #RolesAllowed({"SomeRole"}) on each of my Stateless EJB methods. It throws a security vilotion exception on the Web Service side of the house.
I need to somehow catch this exception and send back a proper message to the client
Is there a way to do all of this without customizing the Weblogic Domain? It feels like I need to manually take control of the Basic Authentication of Weblogic but then I feel like I am stepping the JAAS Login Module of weblogic -- which customizes the domain and I want to avoid.
Use Handlers to intercept the incoming and outgoing requests.

Does Java handle HTTPS encoding behind the scenes when I call my SOAP service?

In Java, I am building a stand alone web service client that manipulates records in a cloud based CRM by using its SOAP API. I generated my classes using the wsimport utility with WSDLs that all have addresses prefixed with https in the port binding section of the WSDL. Is Java handling behind the scenes all the wire-level security simply because the address is https? If so, how can I confirm that the SOAP message is being encrypted? My code does work, and I have not needed to worry about security until now, because I am developing in a staging environment with temporary passwords.
Thank you for your help!
Putting https in the URL will almost always do the trick. Even if your code is not capable of https, the webserver at the other end will almost never allow you to talk in HTTP when using the HTTPS port. At least, I've never seen one that does.
It's not a 100% guarantee that you'd bet your business on, but it is close.
If the code you write works on any website that does require https, you are the rest of the way there in terms of assurances.
You can confirm the traffic is encrypted by running a traffic analyzer aka packet sniffer.

Calling web service that sits on a load balancer with jax-ws returns at http status of 302, but when I use SoapUI it works fine

When I call a web service that sits on a load balancer with jax-ws, it returns
The server sent HTTP status code 302: Moved Temporarily
and then fails, but when I use SoapUI it works fine.
Is there a way that I can configure the service to handle this correctly?
I generated the webservice code using wsimport and make the call as such
NotificationWebService service = new NotificationWebService(wsdlLocation, qName);
NotificationWebServiceSoap serviceSoap = service.getNotificationWebServiceSoap();
String xmlString = serviceSoap.getRSAPublicKeyXMLString();
I'm stuck and I haven't been able to find a solution anywhere so any help would be appreciated.
So after lots of investigation I finally figured out what the problem was. It was all down to redirecting from http to https. From articles I found on the web (can't remember the urls anymore), is that the libraries that the wsdl2java and wsimport stub generators use to do the webservice communication don't allow a http to https redirect follow due to security reasons.
So even though I was generating the stubs from a https wsdl location ie. https://wsdl.location.com?wsdl, when I ran the code to do a webservice call, it was trying to make the call to http://wsdl.location.com which resulted in a redirect request to https://wsdl.location.com, But the http library does not allow that. So it just forwards the 302 http code up as an exception.
Also, there are two web-service urls. One is a testing service which is normal http url and then there is a production server which is over https. So to work around this is all I did is configure the service on the fly to use the end-point I have specified (which is now the https address) by using the BindingProvider class. This also allows me to specify on the fly depending on which environment that is making to call, to use the test url or the production one ie.
NotificationWebService service = new NotificationWebService();
NotificationWebServiceSoap serviceSoap = service.getNotificationWebServiceSoap();
BindingProvider bindingProvider = (BindingProvider) serviceSoap;
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://wsdl.location.com");
String xmlString = serviceSoap.getRSAPublicKeyXMLString();
So in short, if anyone encounters this problem. Make sure if the end point you need point to is on https, that you are making a direct https call and not a http call that will ask for an https redirect. You can check this by examining the serviceSoap while debugging. It will say to which url it is making the call.
I didn't look into or go with the option to configure wsdl2java and wsimport to generate the stubs and force the stubs to use the https call so that I could configure multiple url end-points for different environments.
Yes. You didn't say what you're using for the transport, but if it's something like HttpClient you need to set it up to follow redirects. You may need to fiddle with the auto-generated code, or alternatively, perhaps try a higher level abstraction, like Spring Web Services or CXF.
Reason is the redirection issue on web service call control gets transfered from HTTP to HTTPS. Edit your WSDL file you will find the below code:
original code:
soap:address location="http://www.google.com/Services/Services_xyz.asmx"
changed code:
soap:address location="https://www.google.com/Services/Services_xyz.asmx"
Just change the location attribute HTTP to HTTPS and generate the new stub using the changed WSDL file location.

Categories