Tags

,

hapi Jemeter

hapi Jemeter


package org.apache.jmeter.protocol.java.test;

import java.io.IOException;
import java.io.Serializable;
import java.io.StringReader;
import java.util.Iterator;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient;
import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;

import ca.uhn.hl7v2.DefaultHapiContext;
import ca.uhn.hl7v2.HL7Exception;
import ca.uhn.hl7v2.HapiContext;
import ca.uhn.hl7v2.app.Connection;
import ca.uhn.hl7v2.hoh.sockets.CustomCertificateTlsSocketFactory;
import ca.uhn.hl7v2.hoh.util.HapiSocketTlsFactoryWrapper;
import ca.uhn.hl7v2.llp.LLPException;
import ca.uhn.hl7v2.llp.MinLowerLayerProtocol;
import ca.uhn.hl7v2.model.Message;
import ca.uhn.hl7v2.util.Hl7InputStreamMessageIterator;

public class SendMLLPTest extends AbstractJavaSamplerClient implements Serializable {

	private static final Logger LOG = LoggingManager.getLoggerForClass();

	private static final long serialVersionUID = 1L;

    /** The label to store in the sample result. */
    private String label;

    /** The default value of the Label parameter. */
    private static final String LABEL_DEFAULT = "SendMLLPTest";

    /** The name used to store the Label parameter. */
    private static final String LABEL_NAME = "Label";

    /** The response message to store in the sample result. */
    private String responseMessage;
    /**
     * The default value of the ip parameter.
     */
    public static final String DEFAULT_MLLP_IP_ADDRESS = "10.69.5.164";

    /**
     * The default value of the port parameter.
     */
    public static final long DEFAULT_MLLP_PORT_NUMBER = 7878;

    /**
     * The default value of the timeout parameter in milliseconds.
     */
    public static final int DEFAULT_TIMEOUT = 10000;

    /**
     * The default value of the certificate parameter.
     */
    public static final String DEFAULT_CERTIFICATE = "C:\\keystores\\client_DIT.jks";

    /**
     * The default value of the certificate password parameter.
     */
    public static final String DEFAULT_PASSWORD = "Keys04QA";

    private static String eol = System.getProperty("line.separator");

    /**
     * The default value of the request parameter that is parameterized for using with JMeter.
     */
    public static final String DEFAULT_REQUEST = "MSH|^~\\&|SendingApplication|SendingFacility|ReceivingApplication|RceivingFacility|20101004143744||QBP^Q22^QBP_Q21|NIST-101004143744188|T|2.5" + eol +
"QPD|IHE PDQ Query|${tcn}_${tcName}|@PID.3.1^${Extension}~@PID.3.4.2^${OID}~@PID.3.4.3^ISO~@PID.5.1^${lName}~@PID.5.2^${fName}~@PID.5.3^${mName}~@PID.5.4^${Sufname}~@PID.5.5^${Prefname}~@PID.5.6^${Degree}~@PID.5.7^${NameType}~@PID.7.1^${BirthTime}~@PID.8.1^${Sex}~@PID.11.1^${StrLAddr}~@PID.11.2^${StrLine2}~@PID.11.3^${City}~@PID.11.4^${Province}~@PID.11.5^${Zip}~@PID.11.6^${Country}~@PID.11.7^${AddrType}~@PID.13.2^${TelUseCode}~@PID.13.4^${Email}~@PID.13.5^${CntrCode}~@PID.13.6^${Area}~@PID.13.7^${LocalNum}~@PID.13.8^${Extens}|" + eol +
"RCP|I";

    private int timeout;
    private String ip;
    private long port;
    private String certificate;
    private String password;
    private String request;

    // The name of the sampler
    private String name;

    /** The response message to store in the sample result. */
    private String response;

    /** The default value of the ResponseMessage parameter. */
    private static final String DEFAULT_RESPONSE_MESSAGE = "";

    /** The default value of the ResponseMessage parameter. */
    private static final String RESPONSE_MESSAGE_DEFAULT = "";

    /** The name used to store the ResponseMessage parameter. */
    private static final String RESPONSE_MESSAGE_NAME = "ResponseMessage";

    /** The response code to be stored in the sample result. */
    private String responseCode;

    /** The default value of the ResponseCode parameter. */
    private static final String RESPONSE_CODE_DEFAULT = "AA";

    /** The name used to store the ResponseCode parameter. */
    private static final String RESPONSE_CODE_NAME = "ResponseCode";

    /** The sampler data (shown as Request Data in the Tree display). */
    private String samplerData;

    /** The default value of the SamplerData parameter. */
    private static final String SAMPLER_DATA_DEFAULT = "";

    /** The name used to store the SamplerData parameter. */
    private static final String SAMPLER_DATA_NAME = "SamplerData";

    /** Holds the result data (shown as Response Data in the Tree display). */
    private String resultData;

    /** The default value of the ResultData parameter. */
    private static final String RESULT_DATA_DEFAULT = "";

    /** The name used to store the ResultData parameter. */
    private static final String RESULT_DATA_NAME = "ResultData";

    /** The success status to be stored in the sample result. */
    private boolean success;

    /** The default value of the Success Status parameter. */
    private static final String SUCCESS_DEFAULT = "OK";

    /** The name used to store the Success Status parameter. */
    private static final String SUCCESS_NAME = "Status";

    /**
     * Default constructor for <code>SleepTest</code>.
     *
     * The Java Sampler uses the default constructor to instantiate an instance
     * of the client class.
     */
    public SendMLLPTest() {
        LOG.debug(whoAmI() + "\tConstruct");
    }

    /**
     * Do any initialization required by this client. In this case,
     * initialization consists of getting the values of the IP and
     * Port parameters plus other. It is generally recommended to do any
     * initialization such as getting parameter values in the setupTest method
     * rather than the runTest method in order to add as little overhead as
     * possible to the test.
     *
     * @param context
     *            the context to run with. This provides access to
     *            initialization parameters.
     */
    @Override
    public void setupTest(JavaSamplerContext context) {
        if (LOG.isDebugEnabled()) {
            LOG.debug(whoAmI() + "\tsetupTest()");
            listParameters(context);
        }
        timeout = context.getIntParameter("TIMEOUT", DEFAULT_TIMEOUT);
        ip = context.getParameter("IP", DEFAULT_MLLP_IP_ADDRESS);
        port = context.getLongParameter("PORT", DEFAULT_MLLP_PORT_NUMBER);
        certificate = context.getParameter("CERTIFICATE", DEFAULT_CERTIFICATE);
        password = context.getParameter("PASSWORD", DEFAULT_PASSWORD);
        request = context.getParameter("REQUEST", DEFAULT_REQUEST);
        response = context.getParameter("RESPONSE", DEFAULT_RESPONSE_MESSAGE);

        name = context.getParameter(TestElement.NAME);
    }

	public static String sendMLLPTest(int timeoutArg, String ipArg, long portNoArg, String certArg, String pwdArg, String reqArg) throws HL7Exception, LLPException, InterruptedException, IOException {

		int timeout = timeoutArg;
		String ip = ipArg;
		long portNo = portNoArg;
		String certif = certArg;
		String parola = pwdArg;
		String request = reqArg;
		String resp = null;

		System.setProperty("ca.uhn.hl7v2.app.initiator.timeout", Integer.toString(timeout));

		StringReader reader = new StringReader(request);
		// Create an iterator to iterate over all the messages
		Hl7InputStreamMessageIterator iter = new Hl7InputStreamMessageIterator(
				reader);

		// Create a HapiContext
		HapiContext context = new DefaultHapiContext();
		MinLowerLayerProtocol mllp = new MinLowerLayerProtocol();
		mllp.setCharset("UTF-8");
		context.setLowerLayerProtocol(mllp);

		Connection conn = null;
		 while (iter.hasNext()) {

			if (conn == null) {
				boolean useTls = true;
				long port = portNo;

				CustomCertificateTlsSocketFactory sfac = new CustomCertificateTlsSocketFactory();
				// using jks certificates
				sfac.setKeystoreFilename(certif);
				// default pwd is "Keys04QA"
				sfac.setKeystorePassphrase(parola);
				// Use the following adapter to pass the socket factory to the context
				context.setSocketFactory(new HapiSocketTlsFactoryWrapper(sfac));
				conn = context.newClient(ip, (int) port, useTls);
			}

			try {

				//see if timeout has been set
				String time_out = System.getProperty("ca.uhn.hl7v2.app.initiator.timeout");
				if (time_out != null) {
				    try {
				        Integer timeoutMillis = Integer.parseInt(time_out);
				        System.out.println("Setting Initiator timeout to " + timeoutMillis + " ms");
				    }
				    catch (NumberFormatException e) {
				    	System.out.println(time_out + " is not a valid integer - Initiator is using default timeout");
				    }
				}

				Message next = iter.next();
		        System.out.println("Request:" + eol + next.toString());
				Message response = conn.getInitiator().sendAndReceive(next);
				System.out.println("Response encoded message is:" + eol + response.toString());

		        conn.close();
		        conn = null;

		        context.close();
				resp = response.toString();

			} catch (HL7Exception e) {
				System.out.println("Didn't send out this message or didn't properly handled the HL7 message!");
				e.printStackTrace();

				// Since we failed, close the connection
				conn.close();
				conn = null;
			}
		}
			return resp;
	}

    /*
     * Utility method to set up all the values
     */
    private void setupValues(JavaSamplerContext context) {

        response = context.getParameter(RESPONSE_MESSAGE_NAME, DEFAULT_RESPONSE_MESSAGE);
        responseCode = context.getParameter(RESPONSE_CODE_NAME, RESPONSE_CODE_DEFAULT);
        responseMessage = context.getParameter(RESPONSE_MESSAGE_NAME, RESPONSE_MESSAGE_DEFAULT);

        success = context.getParameter(SUCCESS_NAME, SUCCESS_DEFAULT).equalsIgnoreCase("OK");

        label = context.getParameter(LABEL_NAME, LABEL_DEFAULT);
        if (label.length() == 0) {
            label = context.getParameter(TestElement.NAME); // default to name of element
        }

        samplerData = context.getParameter(SAMPLER_DATA_NAME, SAMPLER_DATA_DEFAULT);
        resultData = context.getParameter(RESULT_DATA_NAME, RESULT_DATA_DEFAULT);
    }

	@Override
	public SampleResult runTest(JavaSamplerContext context) {
		setupValues(context);

		request = context.getParameter("REQUEST", DEFAULT_REQUEST);

		SampleResult results = new SampleResult();

		results.setSampleLabel(name);
		results.setSuccessful(success);
        results.setResponseMessage(responseMessage);
        results.setSampleLabel(label);

        samplerData = request;

        if (samplerData != null &amp;&amp; samplerData.length() &gt; 0) {
            results.setSamplerData(samplerData);
        }

        // Record sample start time.
        results.sampleStart();

		try {
			response = sendMLLPTest(timeout,ip,port,certificate,password,request);
			resultData = response;
	        if (resultData != null &amp;&amp; resultData.length() &gt; 0) {
	            results.setResponseData(resultData, null);
	            results.setDataType(SampleResult.TEXT);
	        }
			results.setSuccessful(success);

		} catch (HL7Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (LLPException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
            LOG.warn("JavaTest: interrupted.");
            results.setSuccessful(true);
			e.printStackTrace();
		} catch (IOException e) {
            LOG.error("JavaTest: error during sample", e);
            results.setSuccessful(false);
			e.printStackTrace();
        } finally {
            // Record end time and populate the results.
            results.sampleEnd();
        }

        if (LOG.isDebugEnabled()) {
            LOG.debug(whoAmI() + "\trunTest()" + "\tTime:\t" + results.getTime());
            listParameters(context);
        }

		return results;
	}

    /**
     * Provide a list of parameters which this test supports. Any parameter
     * names and associated values returned by this method will appear in the
     * GUI by default so the user doesn't have to remember the exact names. The
     * user can add other parameters which are not listed here. If this method
     * returns null then no parameters will be listed. If the value for some
     * parameter is null then that parameter will be listed in the GUI with an
     * empty value.
     *
     * @return a specification of the parameters used by this test which should
     *         be listed in the GUI, or null if no parameters should be listed.
     */
    @Override
    public Arguments getDefaultParameters() {
        Arguments params = new Arguments();
        params.addArgument(LABEL_NAME, LABEL_DEFAULT);
        params.addArgument("IP", String.valueOf(DEFAULT_MLLP_IP_ADDRESS));
        params.addArgument("PORT", String.valueOf(DEFAULT_MLLP_PORT_NUMBER));
        params.addArgument("TIMEOUT", String.valueOf(DEFAULT_TIMEOUT));
        params.addArgument("CERTIFICATE", String.valueOf(DEFAULT_CERTIFICATE));
        params.addArgument("PASSWORD", String.valueOf(DEFAULT_PASSWORD));
        params.addArgument("REQUEST", String.valueOf(DEFAULT_REQUEST));
        params.addArgument(SUCCESS_NAME, SUCCESS_DEFAULT);
        params.addArgument(RESPONSE_CODE_NAME, RESPONSE_CODE_DEFAULT);

        return params;
    }

    /**
     * Dump a list of the parameters in this context to the debug log.
     * Should only be called if debug is enabled.
     *
     * @param context
     *            the context which contains the initialization parameters.
     */
    private void listParameters(JavaSamplerContext context) {
        Iterator argsIt = context.getParameterNamesIterator();
        while (argsIt.hasNext()) {
            String name = argsIt.next();
            LOG.debug(name + "=" + context.getParameter(name));
        }
    }

    /**
     * Generate a String identifier of this test for debugging purposes.
     * @return a String identifier for this test instance
     */
    private String whoAmI() {
        StringBuilder sb = new StringBuilder();
        sb.append(Thread.currentThread().toString());
        sb.append("@");
        sb.append(Integer.toHexString(hashCode()));
        return sb.toString();
    }
}