com.legstar.proxy.invoke.ServiceProxy.java Source code

Java tutorial

Introduction

Here is the source code for com.legstar.proxy.invoke.ServiceProxy.java

Source

/*******************************************************************************
 * Copyright (c) 2010 LegSem.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     LegSem - initial API and implementation
 ******************************************************************************/
package com.legstar.proxy.invoke;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.legstar.coxb.util.ClassUtil;
import com.legstar.messaging.HostMessageFormatException;
import com.legstar.messaging.LegStarMessage;

/**
 * Proxy service Cultureinfo.
 * <p/>
 * This proxy receives raw host data originating from a mainframe, it determines
 * its format (encapsulated in a LegStarMessage or not) and then calls the
 * appropriate operation proxy invoker.
 * 
 */
public class ServiceProxy implements Serializable {

    /** Serial ID. */
    private static final long serialVersionUID = 9222944155913546563L;

    /** Configuration property giving the operation proxy supported. */
    public static final String OPERATION_PROXY_CLASS_NAME_PROPERTY = "operationProxyClassName";

    /** Default operation proxy. */
    public static final String DEFAULT_OPERATION_PROXY_CLASS_NAME = "com.legstar.proxy.invoke.ReflectOperationProxy";

    /** Logger. */
    private static final Log LOG = LogFactory.getLog(ServiceProxy.class);

    /**
     * Current set of configuration parameters. These are setup at construction
     * time but can be overridden on a per-request basis.
     */
    private Map<String, String> mConfig;

    /** The remote operation supported by this service. */
    private IOperationProxy mOperationProxy;

    /**
     * Create a service proxy and its inner operation proxy.
     * 
     * @param config the initial set of parameters
     * @throws ProxyConfigurationException if configuration is invalid
     */
    public ServiceProxy(final Map<String, String> config) throws ProxyConfigurationException {
        if (config == null) {
            mConfig = new HashMap<String, String>();
        } else {
            mConfig = config;
        }
        mOperationProxy = getOperationProxy(mConfig);
    }

    /**
     * Load the operation proxy named in the configuration or the default one
     * if none is found.
     * 
     * @param config the current configuration
     * @return an instance of the operation proxy
     * @throws ProxyConfigurationException if unable to instantiate the
     *             operation proxy
     */
    private IOperationProxy getOperationProxy(final Map<String, String> config) throws ProxyConfigurationException {
        try {
            String operationProxyClassName = config.get(OPERATION_PROXY_CLASS_NAME_PROPERTY);
            if (operationProxyClassName == null || operationProxyClassName.length() == 0) {
                operationProxyClassName = DEFAULT_OPERATION_PROXY_CLASS_NAME;
            }
            Class<?> clazz = ClassUtil.loadClass(operationProxyClassName);
            Constructor<?> constructor = clazz.getConstructor(Map.class);
            return (IOperationProxy) constructor.newInstance(new Object[] { config });
        } catch (SecurityException e) {
            throw new ProxyConfigurationException(e);
        } catch (IllegalArgumentException e) {
            throw new ProxyConfigurationException(e);
        } catch (ClassNotFoundException e) {
            throw new ProxyConfigurationException(e);
        } catch (NoSuchMethodException e) {
            throw new ProxyConfigurationException(e);
        } catch (InstantiationException e) {
            throw new ProxyConfigurationException(e);
        } catch (IllegalAccessException e) {
            throw new ProxyConfigurationException(e);
        } catch (InvocationTargetException e) {
            if (e.getTargetException() instanceof ProxyConfigurationException) {
                throw (ProxyConfigurationException) e.getTargetException();
            }
            throw new ProxyConfigurationException(e);
        }
    }

    /**
     * Extract raw mainframe data from message envelope if any and then hand
     * over
     * control to an operation proxy invoker.
     * <p/>
     * In the future this will be enhanced to support multiple operations but
     * for now we are limited to one so there is no logic to select an available
     * invoker.
     * 
     * @param config request time configuration parameters. This is meant for
     *            things such as credentials
     * @param requestID a unique identifier for the request
     * @param requestBytes the mainframe request data
     * @return reply data ready for transmission to mainframe
     * @throws ProxyInvokerException if invoke fails
     */
    public byte[] invoke(final Map<String, String> config, final String requestID, final byte[] requestBytes)
            throws ProxyInvokerException {

        try {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Servicing proxy request " + requestID);
            }

            /* Detect if client is using LegStar messaging. */
            boolean legstarMessaging = false;
            byte[] payload = requestBytes;
            if (LegStarMessage.isLegStarMessage(requestBytes)) {
                legstarMessaging = true;
                payload = LegStarMessage.getContentFromHostBytes(requestBytes);
            }
            /*
             * Invoke the requested operation. Note that we only support
             * single method services so far.
             */
            byte[] replyBytes = getOperationProxy().invoke(config, requestID, payload);

            /* If client uses LegStar message format a reply */
            if (legstarMessaging) {
                return LegStarMessage.getHostBytesFromContent(replyBytes);
            } else {
                return replyBytes;
            }

        } catch (UnsupportedEncodingException e) {
            throw new ProxyInvokerException(e);
        } catch (HostMessageFormatException e) {
            throw new ProxyInvokerException(e);
        }

    }

    /**
     * Same method using default configuration.
     * 
     * @param requestID a unique identifier for the request
     * @param requestBytes the mainframe request data
     * @return reply data ready for transmission to mainframe
     * @throws ProxyInvokerException if invoke fails
     */
    public byte[] invoke(final String requestID, final byte[] requestBytes) throws ProxyInvokerException {
        return invoke(getConfig(), requestID, requestBytes);
    }

    /**
     * @return the current set of configuration parameters
     */
    public Map<String, String> getConfig() {
        return mConfig;
    }

    /**
     * @return the operation proxy
     */
    public IOperationProxy getOperationProxy() {
        return mOperationProxy;
    }

    /**
     * @param operationProxy the operation proxy set
     */
    public void setCultureinfoProxyInvoker(final IOperationProxy operationProxy) {
        mOperationProxy = operationProxy;
    }

}