Interceptors for WebMethods IntegrationServer http responses and requests
Unfortunately, there is no blissful public API for intercepting HTTP requests on the Integration Server.
However, you can use private APIs to do what you want, in order to return an HTTP 503 Service Unavailable
response to an HTTP request GET
or POST
URL /invoke
when the requested service does not exist.
Below is an example class that implements the interface com.wm.app.b2b.server.HTTPHandler
and handles HTTP requests for a directive /invoke
. If the requested service exists, the HTTP request is passed to the built-in Integration Server handler com.wm.app.b2b.server.HTTPInvokeHandler
for processing. If it doesn't exist, an HTTP response code and a message of your choice will be returned to the HTTP client.
import com.wm.app.b2b.server.AccessException;
import com.wm.app.b2b.server.BaseService;
import com.wm.app.b2b.server.HTTPDispatch;
import com.wm.app.b2b.server.HTTPHandler;
import com.wm.app.b2b.server.HTTPInvokeHandler;
import com.wm.app.b2b.server.ProtocolState;
import com.wm.app.b2b.server.ServerAPI;
import com.wm.app.b2b.server.ns.Namespace;
import com.wm.lang.ns.NSName;
import com.wm.util.Config;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* webMethods Integration Server HTTP invoke handler which returns a
* custom HTTP response code and message when the invoked service does
* not exist.
*/
public class MissingServiceResponseHandler implements HTTPHandler {
private static final String DEFAULT_INVOKE_DIRECTIVE = "invoke";
private static final String INVOKE_DIRECTIVE_CONFIG_KEY = "watt.server.invokeDirective";
private int responseCode;
private String responseMessage;
private Set<String> directives;
private Map<String, HTTPHandler> originalHandlers;
private HTTPInvokeHandler invokeHandler;
private boolean registered;
/**
* Constructs a new MissingServiceResponseHandler that returns the specified
* HTTP response code and message when the invoked service does not exist.
* @param responseCode The HTTP response code returned when the invoked
* service does not exist.
* @param responseMessage The HTTP response message returned when the invoked
* service does not exist.
*/
public MissingServiceResponseHandler(int responseCode, String responseMessage) {
this.responseCode = responseCode;
this.responseMessage = responseMessage;
this.directives = getDirectives();
this.originalHandlers = new TreeMap<String, HTTPHandler>();
this.invokeHandler = new HTTPInvokeHandler();
this.registered = false;
}
/**
* Processes an HTTP request; called by the webMethods Integration Server HTTP request dispatcher.
* @param state The HTTP request to be processed.
* @return True if this object was able to process the HTTP request, otherwise false.
* @throws IOException If an I/O problem is encountered reading from or writing to the client socket.
* @throws AccessException If the the HTTP request requires authentication or is not authorized.
*/
@Override
public final boolean process(ProtocolState state) throws IOException, AccessException {
boolean result;
String directive = getDirective(state);
String path = state.getHttpRequestUrl().substring(directive.length());
StringTokenizer tokenizer = new StringTokenizer(path, "/:");
NSName serviceName = null;
BaseService service = null;
if (tokenizer.countTokens() > 1) {
serviceName = NSName.create(tokenizer.nextToken(), tokenizer.nextToken());
service = Namespace.getService(serviceName);
}
if (serviceName == null || service == null) {
// service does not exist, to return custom response code and message
state.setResponse(responseCode, responseMessage);
result = true;
} else {
state.getInvokeState().setService(service);
result = invokeHandler._process(state, ServerAPI.getContentHandler(state.getContentType()), serviceName);
}
return result;
}
/**
* Returns the relevant directive that matches the given protocol state.
* @param state The protocol state to resolve the directive against.
* @return The relevant directive that matches the given protocol state.
*/
private String getDirective(ProtocolState state) {
String directive = DEFAULT_INVOKE_DIRECTIVE;
if (!state.getHttpRequestUrl().startsWith(directive)) {
directive = Config.getProperty(DEFAULT_INVOKE_DIRECTIVE, INVOKE_DIRECTIVE_CONFIG_KEY);
}
return directive;
}
/**
* Returns all the configured invoke directives for this Integration Server.
* @return All the configured invoke directives for this Integration Server.
*/
private static Set<String> getDirectives() {
Set<String> directives = new TreeSet<String>();
directives.add(DEFAULT_INVOKE_DIRECTIVE);
String alternateDirective = Config.getProperty(DEFAULT_INVOKE_DIRECTIVE, INVOKE_DIRECTIVE_CONFIG_KEY);
if (!DEFAULT_INVOKE_DIRECTIVE.equals(alternateDirective)) {
directives.add(alternateDirective);
}
return directives;
}
/**
* Registers this object as a handler for the invoke directives with the
* Integration Server HTTP request dispatcher.
*/
public synchronized void register() {
if (!registered) {
for (String directive : directives) {
// save the original handler, so we can restore it later
originalHandlers.put(directive, HTTPDispatch.getHandler(directive));
// replace the original handler with this custom handler
HTTPDispatch.addHandler(directive, this);
}
registered = true;
}
}
/**
* Unregisters this object as a handler of the invoke directives from the
* Integration Server HTTP request dispatcher, and reinstates the original
* handlers.
*/
public synchronized void unregister() {
if (registered) {
for (String directive : directives) {
// remove this custom handler from the dispatcher
HTTPDispatch.removeHandler(directive);
// then restore the original handler
HTTPDispatch.addHandler(directive, originalHandlers.get(directive));
}
registered = false;
}
}
}
An example of using this class looks like this:
// create a new handler, specifying the desired HTTP response code and message
// returned when the requested service does not exist
MissingServiceResponseHandler handler = new MissingServiceResponseHandler(503, "Service Unavailable");
// register our custom handler with the Integration Server HTTP request dispatcher
handler.register();
// ...
// now all HTTP requests to the /invoke directive will be handled by our custom handler
// ...
// unregister our custom handler with the Integration Server HTTP request dispatcher, restoring the built-in invoke handler
handler.unregister();
// ...
// now all HTTP requests to the /invoke directive will revert to being handled by the built-in invoke handler
// ...
source to share