Go to new doc!

+49 228 5552576-0


info@predic8.com

Message Interceptors

The architecture of Membrane Service Proxy is open for extension. To add functionality or to change the behavior, an interceptor can be plugged into the flow of messages. When a message flows through Membrane, the interceptors are called. An interceptor can:

During a normal synchronous exchange an interceptor is called twice. The router invokes the handleRequest method of the interceptor first and passes a reference to an exchange object to the interceptor. At this time the exchange object contains a request message only. Now the interceptor can access, read and modify the request. Then the handleRequest method either returns Outcome.CONTINUE or an Outcome.ABORT to indicate whether the processing of the exchange should be continued.

Message flow through an Interceptor

Figure1: Message flow through an Interceptor

After Membrane has done it’s processing, the request is sent to the server. Then the server does its work and returns a response. Membrane then invokes the interceptor again and passes the exchange reference to the handleResponse method. The exchange object is the same as the one passed to handle Request. But this time it contains a request and a response message.

Lifecycle

An interceptor is a singleton and therefore has only one instance. The instance is configured by a Spring configuration or by an API. If you need a per exchange lifecycle, you can achieve the same by attaching properties to the Exchange object:

public Outcome handleRequest(Exchange exc) throws Exception {
	exchange.setProperty("myobject", new MyObject());
	return Outcome.CONTINUE;
}

public Outcome handleResponse(Exchange exc) throws Exception {
	MyObject o = (MyObject) exchange.getProperty("myobject");
	return Outcome.CONTINUE;
}

In the handleResponse method you get back the object that was put there for the corresponding request.

Interceptor Interface

Listening 1 shows the interceptor Interface.

public interface Interceptor extends XMLElement {

	public Outcome handleRequest(Exchange exc) throws Exception;
	
	public Outcome handleResponse(Exchange exc) throws Exception;

	public Outcome handleAbort(Exchange exc) throws Exception;
	
	public String getDisplayName();
	
	public void setDisplayName(String name);
	
	public String getId();
	
	public void setId(String id);
}
Listing 1: Interceptor Interface
The methods handleRequest and handleResponse are called during the normal processing of an exchange. The property displayName is a human readable desciption that is displayed in the GUI of the Membrane Monitor project that is based on the Membrane Service Proxy. The id is used to reference an interceptor from a proxy definition.

Invocation of Interceptor Methods

Each request

1. acquires, as handleRequest() calls of interceptors return Outcome.CONTINUE, a stack of named interceptors.

2. When the request reached the end of the chain (in most cases this is the HttpClientInterceptor, which forwarded the request to some other HTTP server), each interceptor on the stack is popped and handleResponse() called on it.

The "end of the chain" is simply the first interceptor whose handleRequest() returned Outcome.RETURN instead of Outcome.CONTINUE. This last interceptor is not pushed onto the stack.

(In case interceptor.getFlow() returns RESPONSE (in which case handleRequest() should not be called for this interceptor), the call to handleRequest() is not executed during step 1, but treated as returning Outcome.CONTINUE.)

If an interceptor's handleRequest() or handleResponse() returns Outcome.ABORT, an AbortException is thrown.

If an exception is caught (during steps 1 or 2), each interceptor remaining on the stack is popped and its handleAbort() method is called. After any handleAbort()s have been called, the original exception is rethrown. If handleAbort() throws an exception, it is logged and ignored (processing continues with the next interceptor on the stack).

When the exception is then re-caught in the handler (AbstractHttpHandler) and the exchange does not yet have a response set, a generic error response is used. I/O-related exceptions (even when not related to the incoming connection) cause the connection to be closed. Any other exception is logged and processing continues as usual: the response is sent to the client; then the next request on this connection is handled.

Configuration

Interceptors are configuerd in the monitor-beans.xml or router-beans.xml file. You will find there some examples and comments about the configuration. There are also some examples showing how to use and configure interceptors.

Interceptor Chains

Transport Interceptors

Interceptors that are placed into a transport are invoked for all the messages that are flowing through that transport. See the transport bean in the monitor-beans.xml file.

Proxy Interceptors

Interceptors that are placed into a proxy definition are invoked when a message is matched by that proxy. In the figure below there is a SimpleURLMappingInterceptor that manipulates the URI path of requests matching that rule.

Message Flow through Interceptors

Figure2: Message Flow through Interceptors