Interceptors for WebMethods IntegrationServer http responses and requests

How to configure response headers in Integration Server to http-503

request a service not available in error. Since it doesn't hit my service, I can't use pub.flow:setResponseHeader

to set headers. Is there a way that I can have hooks to set the response header?

+3


source to share


1 answer


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
// ...

      

+1


source







All Articles