com.legstar.host.server.PoolingTest.java Source code

Java tutorial

Introduction

Here is the source code for com.legstar.host.server.PoolingTest.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.host.server;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

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

import com.legstar.messaging.HostEndpoint;
import com.legstar.messaging.LegStarAddress;
import com.legstar.messaging.CommareaPart;
import com.legstar.messaging.LegStarHeaderPart;
import com.legstar.messaging.HeaderPartException;
import com.legstar.messaging.LegStarMessage;
import com.legstar.messaging.LegStarMessagePart;
import com.legstar.messaging.LegStarRequest;
import com.legstar.config.Constants;
import com.legstar.config.PoolingEngineConfig;
import com.legstar.coxb.host.HostData;
import com.legstar.messaging.RequestException;
import com.legstar.messaging.HostEndpoint.AccessStrategy;
import com.legstar.mock.client.MockEndpoint;
import com.legstar.test.coxb.LsfileaeCases;
import com.legstar.work.manager.WorkManagerImpl;

import commonj.work.Work;
import commonj.work.WorkEvent;
import commonj.work.WorkListener;
import commonj.work.WorkManager;

import junit.framework.TestCase;

/**
 * Test the pooling engine.
 *
 */
public class PoolingTest extends TestCase {

    /** Mainframe user ID. */
    private static final String HOST_USERID = "P390";

    /** Mainframe password. */
    private static final String HOST_PASSWORD = "STREAM2";

    /** Number of client threads. */
    private static final int CLIENT_THREADS = 10;

    /** Logger. */
    private final Log _log = LogFactory.getLog(PoolingTest.class);

    /**
     * Try start/stop.
     * @throws Exception if failure
     */
    public void testStartStopEngine() throws Exception {
        EngineHandler engHandler = new EngineHandler(getPoolingEngineConfig());
        engHandler.init();
        Thread.sleep(1000L);
        engHandler.stop();
        Thread.sleep(1000L);
    }

    /**
     * Schedule some basic work.
     * @throws Exception if failure
     */
    public void testScheduleWork() throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(CLIENT_THREADS);
        WorkManager wm = new WorkManagerImpl(executor);
        EngineHandler engHandler = new EngineHandler(getPoolingEngineConfig());
        engHandler.init();

        LegStarAddress address = new LegStarAddress("TheMainframe");
        address.setHostUserID(HOST_USERID);
        address.setHostPassword(HOST_PASSWORD);

        LegStarRequest request = new LegStarRequest("Request01", address, getLsfileaeRequestMessage());
        Client client = new Client(engHandler.getEngine(), "Client01", request);
        wm.schedule(client, new ClientListener());

        Thread.sleep(5000L);
        engHandler.stop();
        executor.shutdownNow();

        assertEquals(LsfileaeCases.getHostBytesHexReply100(),
                HostData.toHexString(request.getResponseMessage().getDataParts().get(0).getContent()));

    }

    /**
     * Address a request to an invalid address.
     * @throws Exception if test fails
     */
    public void testScheduleWorkInvalidAddress() throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(CLIENT_THREADS);
        WorkManager wm = new WorkManagerImpl(executor);
        EngineHandler engHandler = new EngineHandler(getPoolingEngineConfig());
        engHandler.init();

        LegStarAddress address = new LegStarAddress("ThereIsNoSuchMainframe");
        address.setHostUserID(HOST_USERID);
        address.setHostPassword(HOST_PASSWORD);

        LegStarRequest request = new LegStarRequest("Request01", address, getLsfileaeRequestMessage());
        Client client = new Client(engHandler.getEngine(), "Client01", request);
        wm.schedule(client, new ClientListener());

        Thread.sleep(5000L);
        engHandler.stop();
        executor.shutdownNow();
        assertEquals(
                "com.legstar.pool.manager.ConnectionPoolException:"
                        + " No host endpoints matches Address=[hostEndpoint=ThereIsNoSuchMainframe,"
                        + "hostCharset=null," + "hostUserID=P390," + "hostTraceMode=false]",
                request.getException().getMessage());

    }

    /**
     * Schedule some work that is guaranteed to fail.
     * @throws Exception if test fails
     */
    public void testScheduleFailingWork() throws Exception {
        EngineHandler engHandler = new EngineHandler(getPoolingEngineConfig());
        engHandler.init();

        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put(Constants.CICS_PROGRAM_NAME_KEY, "TARATATA");
        map.put(Constants.CICS_LENGTH_KEY, "79");
        map.put(Constants.CICS_DATALEN_KEY, "6");
        List<LegStarMessagePart> inputParts = new ArrayList<LegStarMessagePart>();
        LegStarMessagePart inCommarea = new CommareaPart(HostData.toByteArray("F0F0F0F1F0F0"));
        inputParts.add(inCommarea);
        LegStarHeaderPart dp = new LegStarHeaderPart(map, inputParts.size());
        LegStarMessage requestMessage = new LegStarMessage(dp, inputParts);

        LegStarAddress address = new LegStarAddress("TheMainframe");
        address.setHostUserID(HOST_USERID);
        address.setHostPassword(HOST_PASSWORD);

        LegStarRequest request = new LegStarRequest("testScheduleFailingWork", address, requestMessage);
        synchronized (request) {
            engHandler.getEngine().addRequest(request);
            request.await(3000L, TimeUnit.MILLISECONDS);
        }
        assertTrue(request.getException().getMessage()
                .contains("CICS command=LINK COMMAREA failed, resp=PGMIDERR, resp2="));
        assertEquals(null, request.getResponseMessage());

        Thread.sleep(1000L);
        engHandler.stop();
    }

    /**
     * Schedule multiple simultaneous work units.
     * @throws Exception if test fails
     */
    public void testScheduleMultipleWork() throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(CLIENT_THREADS);
        WorkManager wm = new WorkManagerImpl(executor);
        EngineHandler engHandler = new EngineHandler(getPoolingEngineConfig());
        engHandler.init();

        LegStarAddress address = new LegStarAddress("TheMainframe");
        address.setHostUserID(HOST_USERID);
        address.setHostPassword(HOST_PASSWORD);

        Client[] clients = new Client[3];
        for (int i = 0; i < clients.length; i++) {
            LegStarRequest request = new LegStarRequest("Request01", address, getLsfileaeRequestMessage());
            clients[i] = new Client(engHandler.getEngine(), "Client" + Integer.toString(i), request);
            wm.schedule(clients[i], new ClientListener());
            Thread.sleep(20L);
        }

        /* Time is needed to process these requests */
        Thread.sleep(10000L);
        engHandler.stop();
        executor.shutdownNow();

        for (int i = 0; i < clients.length; i++) {
            assertEquals(LsfileaeCases.getHostBytesHexReply100(), HostData
                    .toHexString(clients[i].getRequest().getResponseMessage().getDataParts().get(0).getContent()));
        }
    }

    /**
     * Test work dispatched in more than one pool.
     * @throws Exception if test fails
     */
    public void testScheduleMultiplePools() throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(CLIENT_THREADS);
        WorkManager wm = new WorkManagerImpl(executor);
        EngineHandler engHandler = new EngineHandler(getPoolingEngineConfig());
        engHandler.init();

        LegStarAddress address1 = new LegStarAddress("TheMainframe");
        address1.setHostUserID(HOST_USERID);
        address1.setHostPassword(HOST_PASSWORD);

        LegStarAddress address2 = new LegStarAddress("TheMainframe");
        address2.setHostUserID("IBMUSER");
        address2.setHostPassword(HOST_PASSWORD);

        Client[] clients = new Client[3];
        for (int i = 0; i < clients.length; i++) {
            LegStarAddress address = ((i % 2) == 0) ? address1 : address2;
            LegStarRequest request = new LegStarRequest("Request01", address, getLsfileaeRequestMessage());
            clients[i] = new Client(engHandler.getEngine(), "Client" + new Integer(i).toString(), request);
            wm.schedule(clients[i], new ClientListener());
        }

        /* Time is needed to process these requests */
        Thread.sleep(10000L);
        engHandler.stop();
        executor.shutdownNow();

        for (int i = 0; i < clients.length; i++) {
            assertEquals(LsfileaeCases.getHostBytesHexReply100(), HostData
                    .toHexString(clients[i].getRequest().getResponseMessage().getDataParts().get(0).getContent()));
        }
    }

    /**
     * @return a formatted LegStarMessage requesting execution of LSFILEAE.
     * @throws HeaderPartException if formatting fails
     */
    private LegStarMessage getLsfileaeRequestMessage() throws HeaderPartException {
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put(Constants.CICS_PROGRAM_NAME_KEY, "LSFILEAE");
        map.put(Constants.CICS_LENGTH_KEY, "79");
        map.put(Constants.CICS_DATALEN_KEY, "6");
        List<LegStarMessagePart> inputParts = new ArrayList<LegStarMessagePart>();
        LegStarMessagePart inCommarea = new CommareaPart(HostData.toByteArray("F0F0F0F1F0F0"));
        inputParts.add(inCommarea);
        LegStarHeaderPart dp = new LegStarHeaderPart(map, inputParts.size());
        return new LegStarMessage(dp, inputParts);
    }

    /**
     * A Client unit of work class.
     *
     */
    private class Client implements Work {

        /** Reference to pooling engine. */
        private Engine mEngine;

        /** Client unique ID. */
        private String mClientID;

        /** The request being processed. */
        private LegStarRequest mRequest;

        /**
         * Constructor.
         * @param engine the scheduling engine
         * @param clientID the client ID
         * @param request the request
         */
        public Client(final Engine engine, final String clientID, final LegStarRequest request) {
            mEngine = engine;
            mClientID = clientID;
            mRequest = request;
        }

        /** {@inheritDoc} */
        public void run() {
            _log.debug("Dispatching Request:" + mClientID);
            synchronized (mRequest) {
                try {
                    mEngine.addRequest(mRequest);
                    mRequest.await(3000L, TimeUnit.MILLISECONDS);
                    if (mRequest.getException() != null) {
                        throw mRequest.getException();
                    } else {
                        if (mRequest.getResponseMessage() == null) {
                            _log.error("Timed out waiting for a reply on Request:" + mClientID);
                        }
                    }
                } catch (InterruptedException e) {
                    _log.error("InterruptedException for Request:" + mClientID + " " + e.getMessage());
                    mRequest.setException(e);
                    e.printStackTrace();
                } catch (RequestException e) {
                    _log.error("RequestException for Request:" + mClientID + " " + e.getMessage());
                    mRequest.setException(e);
                    e.printStackTrace();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }

        /**
         * @return the request
         */
        public LegStarRequest getRequest() {
            return mRequest;
        }

        /**  {@inheritDoc} */
        public boolean isDaemon() {
            return false;
        }

        /**  {@inheritDoc} */
        public void release() {

        }

    }

    /**
     * Client listening class.
     *
     */
    private class ClientListener implements WorkListener {

        /** The work manager has accepted the request.
         * @param arg0 work event*/
        public void workAccepted(final WorkEvent arg0) {
            _log.debug("Client Work accepted.");
        }

        /** The Engine completed its work.
         * @param arg0 work event */
        public void workCompleted(final WorkEvent arg0) {
            if (arg0.getException() != null) {
                _log.fatal("Client crashed", arg0.getException());
            }
            _log.debug("Client stopped.");
        }

        /** Manager rejected that work.
         * @param arg0 work event */
        public void workRejected(final WorkEvent arg0) {
            _log.debug("Client work rejected.");
        }

        /** Work unit has started.
         * @param arg0 work event */
        public void workStarted(final WorkEvent arg0) {
            _log.debug("Client started.");
        }

    }

    /**
     * @return a pooling engine configuratio bean
     */
    public PoolingEngineConfig getPoolingEngineConfig() {
        PoolingEngineConfig config = new PoolingEngineConfig();
        List<HostEndpoint> endpoints = new ArrayList<HostEndpoint>();

        HostEndpoint endpoint1 = new MockEndpoint();
        endpoint1.setName("TheMainframe");
        endpoint1.setHostConnectionfactoryClass("com.legstar.mock.client.MockConnectionFactory");
        endpoint1.setHostAccessStrategy(AccessStrategy.direct);
        endpoints.add(endpoint1);

        HostEndpoint endpoint2 = new MockEndpoint();
        endpoint2.setName("TheOtherMainframe");
        endpoint2.setHostConnectionfactoryClass("com.legstar.mock.client.MockConnectionFactory");
        endpoint2.setHostAccessStrategy(AccessStrategy.pooled);
        endpoint2.setHostConnectionPoolSize(2);
        endpoint2.setPooledInvokeTimeout(2000);
        endpoints.add(endpoint2);
        config.setHostEndpoints(endpoints);
        return config;
    }

}