Package org.codehaus.activemq.producer.sampler

Source Code of org.codehaus.activemq.producer.sampler.ProducerSampler

/**
*
* Copyright 2004 Protique Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
package org.codehaus.activemq.producer.sampler;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.Socket;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.apache.jmeter.config.ConfigTestElement;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jmeter.engine.event.LoopIterationEvent;
import org.apache.jmeter.samplers.AbstractSampler;
import org.apache.jmeter.samplers.Entry;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.testelement.TestListener;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;

import java.text.NumberFormat;

import javax.jms.Session;
import javax.jms.JMSException;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.DeliveryMode;
import javax.jms.Connection;
import javax.jms.Message;

import org.codehaus.activemq.ActiveMQConnectionFactory;
import org.codehaus.activemq.util.IdGenerator;

import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt;

import java.util.List;
import java.util.ArrayList;

/**
* A sampler which understands Tcp requests.
*/
public class ProducerSampler extends AbstractSampler implements TestListener {

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

    public final static String FILENAME = "ProducerSampler.filename";
    public final static String CLASSNAME = "ProducerSampler.classname";
    public final static String URL = "ProducerSampler.url";
    public final static String DURATION = "ProducerSampler.duration";
    public final static String RAMP_UP = "ProducerSampler.ramp_up";
    public final static String NOPROD = "ProducerSampler.noprod";
    public final static String NOSUBJECT = "ProducerSampler.nosubject";
    public final static String DURABLE = "ProducerSampler.durable";
    public final static String TOPIC = "ProducerSampler.topic";
    public final static String TOOL_DEFAULT = "TOOL.DEFAULT";
    public final static String MSGSIZE = "ProducerSampler.msgsize";

    private static final int DEFAULT_DURATION = 5;
    private static final int DEFAULT_RAMP_UP = 1;

    private final static String TCPKEY = "TCP";
    private final static String ERRKEY = "ERR";
    public final static int TIMEOUT = 1000;
    public final static boolean NODELAY = true;

    private static Set allSockets = new HashSet();// Keep track of connections to allow close

    // Otherwise, the response is scanned for these strings
    private final static String STATUS_PREFIX = JMeterUtils.getPropDefault("tcp.status.prefix", "");
    private final static String STATUS_SUFFIX = JMeterUtils.getPropDefault("tcp.status.suffix", "");

    private final static String STATUS_PROPERTIES = JMeterUtils.getPropDefault("tcp.status.properties", "");
    private final static Properties statusProps = new Properties();
    private static boolean haveStatusProps = false;

    protected String[] subjects;
    protected String[] producers;

    public static int counter;
    public static int duration;
    public static int ramp_up;

    private long time = System.currentTimeMillis();
    private NumberFormat formatter = NumberFormat.getInstance();

    private ActiveMQConnectionFactory factory;
    int loops = -1;
    int loopSize = 1000;
    private SynchronizedInt connectionCounter = new SynchronizedInt(0);
    private IdGenerator idGenerator = new IdGenerator();
    private List resources = new ArrayList();
    protected boolean embeddedBroker = false;

    static int answer1 = 0;

    static {

        log.info("Protocol Handler name=" + getClassname());
        log.info("Status prefix=" + STATUS_PREFIX);
        log.info("Status suffix=" + STATUS_SUFFIX);
        log.info("Status properties=" + STATUS_PROPERTIES);
        if (STATUS_PROPERTIES.length() > 0) {
            File f = new File(STATUS_PROPERTIES);
            try {
                statusProps.load(new FileInputStream(f));
                log.info("Successfully loaded properties");
                haveStatusProps = true;
            } catch (FileNotFoundException e) {
                log.info("Property file not found");
            } catch (IOException e) {
                log.info("Property file error " + e.toString());
            }
        }
    }

    /**
     * the cache of TCP Connections
     */
    private static ThreadLocal tp = new ThreadLocal() {

        protected Object initialValue() {
            return new HashMap();
        }
    };

    private transient ProducerClient protocolHandler;

    /**
     * Constructor for ProducerSampler object.
     */
    public ProducerSampler() {

        log.debug("Created " + this);
        protocolHandler = getProtocol();
        log.debug("Using Protocol Handler: " + protocolHandler.getClass().getName());
    }

    /**
     * @return Returns String object containing the error.
     */
    private String getError() {

        Map cp = (Map) tp.get();
        return (String) cp.get(ERRKEY);
    }

    /**
     * @return Returns the username.
     */
    public String getUsername() {

        return getPropertyAsString(ConfigTestElement.USERNAME);
    }

    /**
     * @return Returns the password.
     */
    public String getPassword() {

        return getPropertyAsString(ConfigTestElement.PASSWORD);
    }

    /**
     * @param newFilename - the new filename to set.
     */
    public void setFilename(String newFilename) {

        this.setProperty(FILENAME, newFilename);
    }

    /**
     * @return Returns the filename.
     */
    public String getFilename() {

        return getPropertyAsString(FILENAME);
    }

    /**
     * @return Returns the timeout int object.
     */
    public int getTimeout() {

        return TIMEOUT;
    }

    /**
     * @return Returns if there was a delay.
     */
    public boolean getNoDelay() {

        return NODELAY;
    }

    /**
     * @param newURL - the new url to set.
     */
    public void setURL(String newURL) {

        this.setProperty(URL, newURL);
    }

    /**
     * @return Returns the url.
     */
    public String getURL() {

        return getPropertyAsString(URL);
    }

    /**
     * @param newDuration - the new duration to set.
     */
    public void setDuration(String newDuration) {

        this.setProperty(DURATION, newDuration);
    }

    /**
     * @return Returns the duration.
     */
    public int getDuration() {

        return getPropertyAsInt(DURATION);
    }

    /**
     * @param newRampUp - the new ramp up to set.
     */
    public void setRampUp(String newRampUp) {

        this.setProperty(RAMP_UP, newRampUp);
    }

    /**
     * @return Returns the ramp up.
     */
    public int getRampUp() {

        return getPropertyAsInt(RAMP_UP);
    }

    /**
     * @param newDurable - the new durable to set.
     */
    public void setDurable(String newDurable) {

        this.setProperty(DURABLE, newDurable);
    }

    /**
     * @return Returns whether message is durable.
     */
    public boolean getDurable() {

        return getPropertyAsBoolean(DURABLE);
    }

    /**
     * @param newTopic - the new topic to set.
     */
    public void setTopic(String newTopic) {

        this.setProperty(TOPIC, newTopic);
    }

    /**
     * @return Return whether the message is topic.
     */
    public boolean getTopic() {

        return getPropertyAsBoolean(TOPIC);
    }

    /**
     * @param newMsgSize - the new message size to set.
     */
    public void setMsgSize(String newMsgSize) {

        this.setProperty(MSGSIZE, newMsgSize);
    }

    /**
     * @return Returns the message size.
     */
    public int getMsgSize() {

        return getPropertyAsInt(MSGSIZE);
    }

    /**
     * @param newNoProd - the number of producer to set.
     */
    public void setNoProd(String newNoProd) {

        this.setProperty(NOPROD, newNoProd);
    }

    /**
     * @return Returns the number of producers.
     */
    public int getNoProd() {

        return getPropertyAsInt(NOPROD);
    }

    /**
     * @param newNoSubject - the new number of subject to set.
     */
    public void setNoSubject(String newNoSubject) {

        this.setProperty(NOSUBJECT, newNoSubject);
    }

    /**
     * @return Return the number of subject.
     */
    public int getNoSubject() {

        return getPropertyAsInt(NOSUBJECT);
    }

    /**
     * Returns a formatted string label describing this sampler
     * Example output:
     * Tcp://Tcp.nowhere.com/pub/README.txt
     *
     * @return a formatted string label describing this sampler
     */
    public String getLabel() {

        return (this.getURL());
    }

    /**
     * Return the object producer class name.
     *
     * @return Returns the classname of the producer.
     */
    private static String getClassname() {

        String className = JMeterUtils.getPropDefault("tcp.prod.handler", "ProducerClientImpl");
        return className;
    }

    private static final String protoPrefix = "org.codehaus.activemq.producer.sampler.";

    /**
     * Returns the Class object of the running producer.
     *
     * @param className
     * @return
     */
    private Class getClass(String className) {

        Class c = null;

        try {
            c = Class.forName(className
                              , false, Thread.currentThread().getContextClassLoader());
        } catch (ClassNotFoundException e) {
            try {
                c = Class.forName(protoPrefix + className
                                  , false, Thread.currentThread().getContextClassLoader());
            } catch (ClassNotFoundException e1) {
                log.error("Could not find protocol class " + className);
            }
        }
        return c;
    }

    /**
     * Retrieves the protocol.
     *
     * @return Returns the protocol.
     */
    private ProducerClient getProtocol() {

        ProducerClient ProducerClient = null;
        Class javaClass = getClass(getClassname());
        try {
            ProducerClient = (ProducerClient) javaClass.newInstance();
            if (log.isDebugEnabled()) {
                log.debug(this
                          + "Created: "
                          + getClassname()
                          + "@"
                          + Integer.toHexString(ProducerClient.hashCode()));
            }
        } catch (Exception e) {
            log.error(this + " Exception creating: " + getClassname(), e);
        }
        return ProducerClient;
    }

    /**
     * Retrieves the sample as SampleResult object. There are times that this
     * is ignored.
     *
     * @param e - Entry object.
     * @return Returns the sample result.
     */
    public SampleResult sample(Entry e) {// Entry tends to be ignored ...

        log.debug(getLabel() + " " + getFilename() + " " + getUsername() + " " + getPassword());

        SampleResult res = new SampleResult();
        res.setSampleLabel(getName());
        res.setSamplerData(getURL());
        res.sampleStart();

        try {
            //run the benchmark tool code
            this.run();
        } catch (Exception ex) {
            log.debug("", ex);
            res.setResponseCode("500");
            res.setResponseMessage(ex.toString());
        }

        //Calculate response time
        res.sampleEnd();

        // Set if we were successful or not
        res.setSuccessful(true);

        return res;
    }

    /**
     * Checks if there is a response in the server.
     *
     * @param rc response code
     * @return whether this represents success or not
     */
    private boolean checkResponseCode(String rc) {

        if ((rc.compareTo("400") >= 0) && (rc.compareTo("499") <= 0)) {
            return false;
        }

        if (rc.compareTo("500") >= 0 && rc.compareTo("599") <= 0) {
            return false;
        }

        return true;
    }

    /**
     * Disconnects the session to the server.
     */
    private void disconnectAll() {

        synchronized (allSockets) {

            Iterator i = allSockets.iterator();

            while (i.hasNext()) {
                Socket socket = (Socket) i.next();
                try {
                    socket.close();
                } catch (IOException e) {
                    log.warn("Error closing socket ", e);
                } finally {
                    i.remove();
                }
            }
        }
    }

    /**
     * Logs the start of the test. This is called only once
     * per class.
     */
    public void testStarted() {

        log.debug(this + " test started");
    }

    /**
     * Logs the end of the test. This is called only once per
     * class.
     */
    public void testEnded() {

        log.debug(this + " test ended");
        disconnectAll();
    }

    /**
     * Logs the host at the start of the test.
     *
     * @param host - the host to be logged.
     */
    public void testStarted(String host) {

        log.debug(this + " test started on " + host);
    }

    /**
     * Logs the host at the end of the test.
     *
     * @param host - the host to be logged.
     */
    public void testEnded(String host) {

        log.debug(this + " test ended on " + host);
        disconnectAll();
    }

    /**
     * Logs the iteration event.
     *
     * @param event
     */
    public void testIterationStart(LoopIterationEvent event) {

        log.debug(this + " test iteration start on " + event.getIteration());
    }

    /**
     * Runs and publish the message.
     *
     * @throws Exception
     */
    public void run() throws Exception {

        start();
        publish();
    }

    /**
     * Creates the subject that will be published.
     */
    public void start() {

        //create the subjects
        subjects = new String[getNoSubject()];
        for (int i = 0; i < getNoSubject(); i++) {
            subjects[i] = TOOL_DEFAULT + i;
        }

        // set the duration       
        if (getDuration() == 0) {
            duration = DEFAULT_DURATION;
        } else {
            duration = getDuration();
        }
       
        //set the ramp_up
        if (getRampUp() == 0) {
            ramp_up = DEFAULT_RAMP_UP;
        } else {
            ramp_up = getRampUp();
        }
    }

    /**
     * Retrieves the message then sends it via tcp.
     *
     * @throws Exception
     */
    protected void publish() throws Exception {

        final String text = getMessage();

        for (int i = 0; i < getNoProd(); i++) {
            final String subject = subjects[i % getNoSubject()];
            Thread thread = new Thread() {
                public void run() {
                    try {
                        publish(text, subject);
                    } catch (JMSException e) {
                        //System.out.println("Caught: " + e);
                        e.printStackTrace();
                    }
                }
            };
            thread.start();
        }
    }

    /**
     * @return Returns the message.
     */
    protected String getMessage() {

        StringBuffer buffer = new StringBuffer();

        for (int i = 0; i < getMsgSize(); i++) {
            char ch = 'X';
            buffer.append(ch);
        }

        return buffer.toString();
    }

    /**
     * Sends the information from the client via tcp.
     *
     * @param text    - message that is sent.
     * @param subject - subject of the message to be sent.
     * @throws JMSException
     */
    protected void publish(String text, String subject) throws JMSException {

        Session session = createSession();
        Destination destination = createDestination(session, subject);
        MessageProducer publisher = session.createProducer(destination);

        if (getDurable()) {
            publisher.setDeliveryMode(DeliveryMode.PERSISTENT);
        } else {
            publisher.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
        }

        if (loops <= 0) {
            while (true) {
                publishLoop(session, publisher, text);
            }
        } else {
            for (int i = 0; i < loops; i++) {
                publishLoop(session, publisher, text);
            }
        }
    }

    /**
     * Creates a new Session object.
     *
     * @return Returns a new Session object.
     * @throws JMSException
     */
    protected Session createSession() throws JMSException {

        if (factory == null) {
            factory = createFactory();
        }

        Connection connection = factory.createConnection();
        int value = connectionCounter.increment();

        if (getDurable()) {
            connection.setClientID(idGenerator.generateId());
        }

        addResource(connection);
        connection.start();

        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        addResource(session);
        return session;
    }

    /**
     * Creates a Destination object through Session using subject.
     *
     * @param session - Session used to create the Destination.
     * @param subject - the subject of the Destination to be created.
     * @return Returns Destination object.
     * @throws JMSException
     */
    protected Destination createDestination(Session session, String subject) throws JMSException {

        if (getTopic()) {
            return session.createTopic(subject);
        } else {
            return session.createQueue(subject);
        }
    }

    /**
     * Sends a message through MessageProducer objects.
     *
     * @param session   - Session oject.
     * @param publisher - MessageProducer object.
     * @param text      - text that is used to create Message object.
     * @throws JMSException
     */
    protected void publishLoop(Session session, MessageProducer publisher, String text) throws JMSException {

        for (int i = 0; i < loopSize; i++) {
            Message message = session.createTextMessage(text);
            publisher.send(message);
            count(1);
        }
    }

    /**
     * Creates an instance of ActiveMQConnectionFactory object and
     * sets value to the new objects useEmbeddedBroker variable
     * depending on the its instance variable embeddedBroker.
     *
     * @return Instance of ActiveMQConnectionFactory object.
     */
    protected ActiveMQConnectionFactory createFactory() {

        ActiveMQConnectionFactory answer = new ActiveMQConnectionFactory(getURL());

        if (embeddedBroker) {
            answer.setUseEmbeddedBroker(true);
        }

        return answer;
    }

    /**
     * Add a new object to resource.
     *
     * @param resource - Object added to resource.
     */
    protected void addResource(Object resource) {
       
        resources.add(resource);
    }

    /**
     * Increments the int variable.
     *
     * @param count - variable incremented.
     */
    protected synchronized void count(int count) {

        counter += count;
    }

    /**
     * @return the current number of messages sent.
     */
    public static synchronized int resetCount() {

        int answer = counter;
        counter = 0;
        return answer;
    }

}
TOP

Related Classes of org.codehaus.activemq.producer.sampler.ProducerSampler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.