Tuesday, December 9, 2014

How to implement interceptor for UDDI Service calls

This post describes how to implement interceptor for all external service calls done through UDDI Connector.

Why Interceptor ?

  • End Point not static : You might change the end point for every UDDI call based on some logic. This is a general scenario where in you need to change the end point of all the services for every deployment. This can be achieved by changing every web service's end point by going to external services configuration but this is a tedious task as one needs to do it after every deployment and also to all the web services in the solution. One might think about the effort of changing 10 interfaces having 10 web services in each interface.
  • Defaulting few tags : A Scenario where for every UDDI call there are many tags which are to be defaulted and this should not be taken at process level (BPM level) as it(defaulting) has to be implemented whenever a UDDI service to be called.
  • Tweaking the request : A possible scenario of encrypting/decrypting some or all of the request tags.
  • Tweaking the response : A possible scenario of encrypting/decrypting some or all of the response tags.
  • Audit Log : Auditing every UDDI call.
There might be many more scenarios which might need the concept of Interceptor to be implemented.

How ?
  • We need to write a class which extends Customizer class of UDDIConn.jar. This Customizer class is an abstract class, hence a class which extends this class has to implement all the abstract methods among which OnRequest and OnResponse are also the methods.
  • A Sample scenario in which request and response is logged is shown below,

package better.faster.smarter.development.uddi.interceptor;

import com.eibus.applicationconnector.uddi.AuthenticationDetails;
import com.eibus.applicationconnector.uddi.Customizer;
import com.eibus.applicationconnector.uddi.IHTTPObject;
import com.eibus.applicationconnector.uddi.InterceptorException;
import com.eibus.applicationconnector.uddi.UserInfo;
import com.eibus.util.logger.CordysLogger;
import com.eibus.util.logger.Severity;
import com.eibus.xml.nom.Node;
public class CustomInterceptor extends Customizer {
private static CordysLogger logger = CordysLogger.getCordysLogger(CustomInterceptor.class);@Override
public void initialize(int arg0) {
// TODO Auto-generated method stub
}
@Override
public void onHttpRequest(IHTTPObject arg0, UserInfo arg1)
throws InterceptorException {
// TODO Auto-generated method stub
}
@Override
public void onHttpResponse(IHTTPObject arg0, UserInfo arg1)
throws InterceptorException {
// TODO Auto-generated method stub
}
@SuppressWarnings("deprecation")@Override
public void onRequest(int arg0) {
// TODO Auto-generated method stub
logger.log(Severity.WARN, "Writing the request " + Node.writeToString(arg0, true));
}
@SuppressWarnings("deprecation")@Override
public void onResponse(int arg0) {
// TODO Auto-generated method stub
logger.log(Severity.WARN, "Writing the response " + Node.writeToString(arg0, true));
}
@Override
public void onSOAPFault(int arg0) {
// TODO Auto-generated method stub
}
@Override
public AuthenticationDetails getAuthenticationDetails(int arg0, String arg1) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getNewEndpointURL(int arg0, String arg1) {
// TODO Auto-generated method stub
return null;
}
}
  • A Sample scenario of changing the end point is shown below
package com.schneiderelectric.bfoentwebservices.r1;

import com.eibus.applicationconnector.uddi.AuthenticationDetails;
import com.eibus.applicationconnector.uddi.Customizer;
import com.eibus.applicationconnector.uddi.IHTTPObject;
import com.eibus.applicationconnector.uddi.InterceptorException;
import com.eibus.applicationconnector.uddi.UserInfo;
import com.eibus.util.logger.CordysLogger;
import com.eibus.xml.nom.Node;
import com.eibus.xml.xpath.XPath;
public class BFOReqInterceptor extends Customizer
{
  private static final CordysLogger logger = CordysLogger.getCordysLogger(BFOReqInterceptor.class);
  public String getNewEndpointURL(int request, String origURL) {
    int methodNode = XPath.getFirstMatch("//Body/*", null, request);
    String host = Node.getAttribute(methodNode, "SessionURL", null);
    if (host == null) {
      return origURL;
    }
    if (logger.isDebugEnabled())
      logger.debug("Original URL: " + origURL);
    int dblSlashIndex = origURL.indexOf("//");
    int slashIndex = origURL.indexOf("/", dblSlashIndex + 2);
    int colonIndex = origURL.indexOf(":", dblSlashIndex + 2);
    StringBuffer buf = new StringBuffer(origURL);
    buf.replace(dblSlashIndex + 2, colonIndex != -1 ? colonIndex : slashIndex, host);
    if (logger.isDebugEnabled())
      logger.debug("Updated URL: " + buf.toString());
    return buf.toString();
  }
  public AuthenticationDetails getAuthenticationDetails(int paramInt, String paramString) {
    return null;
  }
  public void initialize(int methodImplementation)
  {
  }
  public void onRequest(int request)
  {
  }
  public void onResponse(int response)
  {
  }
  public void onSOAPFault(int soapFault)
  {
  }
  public void onHttpRequest(IHTTPObject arg0, UserInfo arg1)
    throws InterceptorException
  {
  }
  public void onHttpResponse(IHTTPObject arg0, UserInfo arg1)
    throws InterceptorException
  {
  }
}
  • Once the class is developed, we have to make a jar for this package and give this jar as JRE property for UDDI Container.
  • Everything will be useless if you don't change the implementation of the web service for which you need this interceptor to work. Since this is a one time activity, this can be covered in development phase. The changes will go with every deployment.

You need to add the below XML Node to the existing UDDI Service


  <interceptor>
    <class>better.faster.smarter.development.uddi.interceptor.CustomInterceptor</class>
  </interceptor>


No comments:

Post a Comment