Archive

Posts Tagged ‘Services Mediator’

Patterns of System Integration #1: Services mediator

Disclaimer: this pattern does not refer to Oracle´s SOA Suite 11g Mediator, nor any Thomas Erl´s Patterns (although it looks like the implementation of pieces of some of his patterns).

So, give me a brief description on what it is about.

People who are used to work with SOA are, usually, used to work with ESB´s – I say “ESB´s”, plural, to mean different kinds from different vendors of ESB – and BPEL. ESB´s are often used to justify decoupling of clients from service providers. I think it is great, but people usually forget that ESB´s, as long as they are too decoupled from the system, do not provide so much advantages as it should. So, usually, ESB´s are a layer of extra complexity to systems (the exception are some odd situations that don´t fit the usual description). Sometimes, you need some piece of software that is more intimate to the system, that can interact in an easier way to the system (like some easy way to audit calls, log them, place warns on whether systems are responding or not – therefore avoiding issues on being overloaded due to slow responsiveness of external services -, etc.). So, thinking about it, I developed this pattern.

Explain it better, what is it about?

People need to be in control of their applications. People should be in control of their applications. Usually, that´s not what happens to a SOA-based app, because we rely too much on external tools and forget that good things may be done at home, too. So, you don´t need to use a service composition to audit external services I/O, for example. If you would do so by today´s standards, you would build a service to do the auditing, then group the external service and the audit service into one piece of service composition, then offer the composition´s contract to the client… too much work. You should not build separate services unless you need them as services (after all, SOA is about getting the IT to work along with the business, right? So, it should not try to add extra pieces of complexity, like one more service, to the business, right?); so, you should approach the problem with another solution, like intercepting the messages according to your programming language way of doing so.

So, my pattern is about intercepting outgoing messages / incoming responses by building transparent, language-friendly units, in a manner that, if you need extra capabilities but do not want (or do not need) to build extra services, you should consider applying this pattern.

How to do it?

First, you should take the original WSDL and override it, replacing the original address – a technique shown here. I´m gonna call this service “shell service”, from now on. The shell service´s purpose is to provide the capability of adding this extra logic, which means it should be built in the main programming language you use in your application. To build it, you should use the same logic as the mentioned post, but should modify the provider to something like the following:



package com.alesaudate.webservices;

import javax.xml.soap.SOAPMessage;
import java.net.URL;
import java.util.Iterator;
import javax.xml.namespace.QName;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;


public class SOAPProvider {

	public Dispatch<SOAPMessage> getDispatcher (String wsdl, String namespace, String servicename, String portName){

		try {
			//create a representation of the service
			Service service = Service.create(new URL(wsdl), new QName(
					namespace, servicename));

			final Iterator<QName> ports = service.getPorts();

			QName methodToBeCalled = null;

			//Select the port to be called
			if (portName == null)
				methodToBeCalled = ports.next();

			else {
				while (methodToBeCalled == null || !methodToBeCalled.getLocalPart().equals(portName)) {
					methodToBeCalled = ports.next();
				}
			}

			//Create the dispatcher, given the data.
			Dispatch<SOAPMessage> dispatch = service.createDispatch(
					methodToBeCalled, SOAPMessage.class, Service.Mode.MESSAGE);

			return dispatch;
		} catch (Exception e) {
			throw new RuntimeException("Error calling web-service", e);
		}
	}
}
package com.alesaudate.webservices;

import javax.xml.soap.SOAPMessage;
import javax.xml.ws.Provider;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.Service.Mode;

@ServiceMode(Mode.MESSAGE)
@WebServiceProvider(portName="blogSOAP",
		serviceName="blogService",
		targetNamespace="http://alesaudate.com/webservices",
		wsdlLocation="WEB-INF/wsdl/blog.wsdl")
public class MySOAPProvider implements Provider<SOAPMessage>{


	public static final String ORIGINAL_WSDL = "http://localhost/SampleService?wsdl";
	public static final String ORIGINAL_SERVICE = "sampleService";
	public static final String ORIGINAL_PORT = "samplePort";
	public static final String ORIGINAL_NAMESPACE = "sampleNamespace";

	private SOAPProvider provider;
	
	public MySOAPProvider() {
		this.provider = new SOAPProvider();
	}


	//You may add any extra logic here.
	@Override
	public SOAPMessage invoke(SOAPMessage request) {
		Dispatch<SOAPMessage> dispatcher = provider.getDispatcher(ORIGINAL_WSDL, ORIGINAL_NAMESPACE , ORIGINAL_SERVICE,ORIGINAL_PORT);
		SOAPMessage response = dispatcher.invoke(request);
		return response;
	}

}

Just to remind the reader, I would like to mention that this technique has been shown here.

Conclusion

I have shown here a design pattern that I call Services Mediator. Basically, it is the same that an Enterprise Service Bus does, but with the difference that it must be implemented in the same language that the application uses, providing, then, more control to the application programmer. So, at any time the services need some business logic, but does not necessarily need to use services to do so, the programmer may add this logic inside the services shell.