Friday, April 18, 2008

Webservice and SoapUI

I was trying to write a web service client. It had to be a runtime client, which can be configured to call a web service, given a url to a wsdl. I tried using SoapUI. Its nice and easy. My client code went like -
WsdlProject project = new WsdlProject();
WsdlInterface iface = 
  project.importWsdl(
   "http://localhost:8080/axis2/services/HelloWorldService?wsdl",
    true)[0];
for (int i = 0;i < iface.getOperationCount();i++)
{  WsdlOperation operation = 
  (WsdlOperation)iface.getOperationAt(i);
  System.out.println(
(i+1)+ "th opeartion name "+ operation.getName()); // rest goes here... }
the above piece of code would give the list of operations present for the web service. The user selects one of them. A request can be generated by -
WsdlOperation operation = (WsdlOperation) iface.getOperationByName("sayHello");                        
WsdlRequest request = operation.addNewRequest("My request");
String requestStr = operation.createRequest(true);
next part isnt elegant. I just String replaced the "?" to the set the parameter values :P
requestStr = requestStr.replaceAll("[?]","bad, very bad");
Now this can be sent -
request.setRequestContent(requestStr);
WsdlSubmit submit = 
  (WsdlSubmit)request.submit(
     new WsdlSubmitContext(null), 
     false );
Response response = submit.getResponse();
Done.....................
Hey, wait. There is a problem. If the server hosting the web service is down???
I saw that the sending request part had a time out set into it. If the server is down it wud give throw a Connection error. But the importWSDL did not have a timeout. So, if the user is trying to configure the client, when the server is down, or more probable - types in a wrong url, the application hangs. There is no option of giving time outs while importing the wsdl.
After sometime I got out of that string of thought and found a useful bit of code, which checks if the url exists. Good one -
import java.net.*;
import java.io.*;

public class URLUtils {

  public static void main(String s[]) {
    System.out.println(URLUtils.exists("http://www.yahoo.com"));
    System.out.println(URLUtils.exists("http://www.abcdefgh.hhh"));
  }

  public static boolean exists(String URLName){
    try {
      HttpURLConnection.setFollowRedirects(false);
      // note : you may also need
      //HttpURLConnection.setInstanceFollowRedirects(false);
      URL url = new URK(URLName);
      HttpURLConnection con = 
      (HttpURLConnection) url.openConnection();
      con.setRequestMethod("HEAD");
      return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
    }
    catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }
}
The following is doing the same thing but this time we identify ourself to a proxy -
import java.net.*;
import java.io.*;
import java.util.Properties;

public class URLUtils {

  public static void main(String s[]) {
    System.out.println(exists("http://www.yahoo.com"));
    System.out.println(exists("http://www.abcdefgh.hhh"));
  }


  public static boolean exists(String URLName){
    try {
      Properties systemSettings = System.getProperties();
      systemSettings.put("proxySet", "true");
      systemSettings.put("http.proxyHost","proxy.mycompany.local") ;
      systemSettings.put("http.proxyPort", "80") ;

      URL u = new URL(URLName);
      HttpURLConnection con = (HttpURLConnection) u.openConnection();
      //
      // it's not the greatest idea to use a sun.misc.* class
      // Sun strongly advises not to use them since they can 
      // change or go away in a future release so beware.
      //
      sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
      String encodedUserPwd = 
           encoder.encode("domain\\username:password".getBytes());
      con.setRequestProperty("Proxy-Authorization", "Basic " + encodedUserPwd);
      con.setRequestMethod("HEAD");
      System.out.println(con.getResponseCode() + " : " + 
      con.getResponseMessage());
      return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
    }
    catch (Exception e) {
      e.printStackTrace();
      return false;
    }
  }
}
So it wud be like -
if (URLUtils.exists(
  "http://localhost:8080/axis2/services/HelloWorldService?wsdl")
  )
{
  WsdlInterface iface = 
  project.importWsdl(
    "http://localhost:8080/axis2/services/HelloWorldService?wsdl",
    true)[0];
  // rest goes here....
}
Now done................................... :D

No comments: