You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ro...@apache.org on 2012/04/05 18:04:16 UTC

svn commit: r1309918 [4/10] - in /qpid/trunk/qpid/java: ./ perftests/ perftests/etc/ perftests/example/ perftests/example/brokerconfig/ perftests/src/ perftests/src/main/ perftests/src/main/java/ perftests/src/main/java/org/ perftests/src/main/java/org...

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantExecutorRegistry.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantExecutorRegistry.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantExecutorRegistry.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantExecutorRegistry.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.client;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ParticipantExecutorRegistry
+{
+    private final Set<ParticipantExecutor> _participantExecutors = Collections.synchronizedSet(new HashSet<ParticipantExecutor>());
+
+    public void add(ParticipantExecutor participantExecutor)
+    {
+        _participantExecutors.add(participantExecutor);
+    }
+
+    public void clear()
+    {
+        _participantExecutors.clear();
+    }
+
+    public Collection<ParticipantExecutor> executors()
+    {
+        return Collections.unmodifiableSet(_participantExecutors);
+    }
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantResultFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantResultFactory.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantResultFactory.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/ParticipantResultFactory.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.client;
+
+import java.util.Date;
+
+import org.apache.qpid.disttest.message.ConsumerParticipantResult;
+import org.apache.qpid.disttest.message.CreateConsumerCommand;
+import org.apache.qpid.disttest.message.CreateParticpantCommand;
+import org.apache.qpid.disttest.message.CreateProducerCommand;
+import org.apache.qpid.disttest.message.ParticipantResult;
+import org.apache.qpid.disttest.message.ProducerParticipantResult;
+
+public class ParticipantResultFactory
+{
+    public ConsumerParticipantResult createForConsumer(String participantName, String clientRegisteredName, CreateConsumerCommand command, int numberOfMessagesReceived, int payloadSize, long totalPayloadReceived, Date start, Date end)
+    {
+        ConsumerParticipantResult consumerParticipantResult = new ConsumerParticipantResult();
+
+        setTestProperties(consumerParticipantResult, command, participantName, clientRegisteredName);
+        setTestResultProperties(consumerParticipantResult, numberOfMessagesReceived, payloadSize, totalPayloadReceived, start, end);
+
+        consumerParticipantResult.setTopic(command.isTopic());
+        consumerParticipantResult.setDurableSubscription(command.isDurableSubscription());
+        consumerParticipantResult.setBrowsingSubscription(command.isBrowsingSubscription());
+        consumerParticipantResult.setSelector(command.getSelector() != null);
+        consumerParticipantResult.setNoLocal(command.isNoLocal());
+        consumerParticipantResult.setSynchronousConsumer(command.isSynchronous());
+
+        return consumerParticipantResult;
+    }
+
+    public ProducerParticipantResult createForProducer(String participantName, String clientRegisteredName, CreateProducerCommand command, int numberOfMessagesSent, int payloadSize, long totalPayloadSent, Date start, Date end)
+    {
+        final ProducerParticipantResult participantResult = new ProducerParticipantResult();
+
+        participantResult.setStartDelay(command.getStartDelay());
+        participantResult.setDeliveryMode(command.getDeliveryMode());
+        participantResult.setPriority(command.getPriority());
+        participantResult.setInterval(command.getInterval());
+        participantResult.setTimeToLive(command.getTimeToLive());
+
+        setTestProperties(participantResult, command, participantName, clientRegisteredName);
+
+        setTestResultProperties(participantResult, numberOfMessagesSent, payloadSize, totalPayloadSent, start, end);
+
+        return participantResult;
+    }
+
+    private void setTestResultProperties(final ParticipantResult participantResult, int numberOfMessagesSent, int payloadSize, long totalPayloadReceived, Date start, Date end)
+    {
+        participantResult.setNumberOfMessagesProcessed(numberOfMessagesSent);
+        participantResult.setPayloadSize(payloadSize);
+        participantResult.setTotalPayloadProcessed(totalPayloadReceived);
+        participantResult.setStartDate(start);
+        participantResult.setEndDate(end);
+    }
+
+    private void setTestProperties(final ParticipantResult participantResult, CreateParticpantCommand command, String participantName, String clientRegisteredName)
+    {
+        participantResult.setParticipantName(participantName);
+        participantResult.setRegisteredClientName(clientRegisteredName);
+        participantResult.setBatchSize(command.getBatchSize());
+        participantResult.setMaximumDuration(command.getMaximumDuration());
+
+    }
+
+    public ParticipantResult createForError(String participantName, String clientRegisteredName, String errorMessage)
+    {
+        ParticipantResult result = new ParticipantResult();
+        result.setParticipantName(participantName);
+        result.setRegisteredClientName(clientRegisteredName);
+        result.setErrorMessage(errorMessage);
+
+        return result;
+    }
+
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/ProducerParticipant.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/ProducerParticipant.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/ProducerParticipant.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/ProducerParticipant.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.client;
+
+import java.util.Date;
+import java.util.NavigableSet;
+import java.util.TreeSet;
+
+import javax.jms.Message;
+
+import org.apache.qpid.disttest.DistributedTestException;
+import org.apache.qpid.disttest.jms.ClientJmsDelegate;
+import org.apache.qpid.disttest.message.CreateProducerCommand;
+import org.apache.qpid.disttest.message.ParticipantResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ProducerParticipant implements Participant
+{
+    private static final Logger LOGGER = LoggerFactory.getLogger(ProducerParticipant.class);
+
+    private final ClientJmsDelegate _jmsDelegate;
+
+    private final CreateProducerCommand _command;
+
+    private ParticipantResultFactory _resultFactory;
+
+    public ProducerParticipant(final ClientJmsDelegate jmsDelegate, final CreateProducerCommand command)
+    {
+        _jmsDelegate = jmsDelegate;
+        _command = command;
+        _resultFactory = new ParticipantResultFactory();
+    }
+
+    @Override
+    public ParticipantResult doIt(String registeredClientName) throws Exception
+    {
+        if (_command.getMaximumDuration() == 0 && _command.getNumberOfMessages() == 0)
+        {
+            throw new DistributedTestException("number of messages and duration cannot both be zero");
+        }
+
+        long expectedDuration = _command.getMaximumDuration() - _command.getStartDelay();
+
+        doSleepForStartDelay();
+
+        final long startTime = System.currentTimeMillis();
+
+        Message lastPublishedMessage = null;
+        int numberOfMessagesSent = 0;
+        long totalPayloadSizeOfAllMessagesSent = 0;
+        NavigableSet<Integer> allProducedPayloadSizes = new TreeSet<Integer>();
+
+        while (true)
+        {
+            numberOfMessagesSent++;
+
+            lastPublishedMessage = _jmsDelegate.sendNextMessage(_command);
+
+            int lastPayloadSize = _jmsDelegate.calculatePayloadSizeFrom(lastPublishedMessage);
+            totalPayloadSizeOfAllMessagesSent += lastPayloadSize;
+            allProducedPayloadSizes.add(lastPayloadSize);
+
+            if (LOGGER.isTraceEnabled())
+            {
+                LOGGER.trace("message " + numberOfMessagesSent + " sent by " + this);
+            }
+
+            final boolean batchLimitReached = _command.getBatchSize() <= 0
+                            || numberOfMessagesSent % _command.getBatchSize() == 0;
+
+            if (batchLimitReached)
+            {
+                _jmsDelegate.commitOrAcknowledgeMessage(lastPublishedMessage, _command.getSessionName());
+
+                if (_command.getInterval() > 0)
+                {
+                    // sleep for given time
+                    Thread.sleep(_command.getInterval());
+                }
+            }
+
+            if (_command.getNumberOfMessages() > 0 && numberOfMessagesSent >= _command.getNumberOfMessages()
+                            || expectedDuration > 0 && System.currentTimeMillis() - startTime >= expectedDuration)
+            {
+                break;
+            }
+        }
+
+        // commit the remaining batch messages
+        if (_command.getBatchSize() > 0 && numberOfMessagesSent % _command.getBatchSize() != 0)
+        {
+            _jmsDelegate.commitOrAcknowledgeMessage(lastPublishedMessage, _command.getSessionName());
+        }
+
+        Date start = new Date(startTime);
+        Date end = new Date();
+        int payloadSize = getPayloadSizeForResultIfConstantOrZeroOtherwise(allProducedPayloadSizes);
+
+        return _resultFactory.createForProducer(
+                getName(),
+                registeredClientName,
+                _command,
+                numberOfMessagesSent,
+                payloadSize,
+                totalPayloadSizeOfAllMessagesSent, start, end);
+    }
+
+    private int getPayloadSizeForResultIfConstantOrZeroOtherwise(NavigableSet<Integer> allPayloadSizes)
+    {
+        return allPayloadSizes.size() == 1 ? allPayloadSizes.first() : 0;
+    }
+
+    private void doSleepForStartDelay()
+    {
+        if (_command.getStartDelay() > 0)
+        {
+            // start delay is specified. Sleeping...
+            try
+            {
+                Thread.sleep(_command.getStartDelay());
+            }
+            catch (final InterruptedException e)
+            {
+                Thread.currentThread().interrupt();
+            }
+        }
+    }
+
+    @Override
+    public void releaseResources()
+    {
+        _jmsDelegate.closeTestProducer(_command.getParticipantName());
+    }
+
+    @Override
+    public String getName()
+    {
+        return _command.getParticipantName();
+    }
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/GeneratedPropertySupport.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/GeneratedPropertySupport.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/GeneratedPropertySupport.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/GeneratedPropertySupport.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.client.property;
+
+/**
+ * Provides support to generate message property values.
+ */
+public abstract class GeneratedPropertySupport implements GeneratedPropertyValue
+{
+    private Object _lastValue;
+
+    public GeneratedPropertySupport()
+    {
+        super();
+        _lastValue = null;
+    }
+
+    @Override
+    public Object getValue()
+    {
+        Object result = nextValue();
+        result = evaluate(result);
+        synchronized(this)
+        {
+            _lastValue = result;
+        }
+        return result;
+    }
+
+    protected Object evaluate(Object result)
+    {
+        while (result instanceof PropertyValue)
+        {
+            result = ((PropertyValue)result).getValue();
+        }
+        return result;
+    }
+
+    public abstract Object nextValue();
+
+    public synchronized Object getLastValue()
+    {
+        return _lastValue;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "GeneratedPropertyValue [value=" + getLastValue() + ", @def=" + getDefinition() + "]";
+    }
+
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/GeneratedPropertyValue.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/GeneratedPropertyValue.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/GeneratedPropertyValue.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/GeneratedPropertyValue.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.client.property;
+
+/**
+ * Provides operations to generate message property values.
+ */
+public interface GeneratedPropertyValue extends PropertyValue
+{
+    public String getDefinition();
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/ListPropertyValue.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/ListPropertyValue.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/ListPropertyValue.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/ListPropertyValue.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.client.property;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Provides property values from the underlining list of items.
+ */
+public class ListPropertyValue extends GeneratedPropertySupport
+{
+    public static final String DEF_VALUE = "list";
+    private List<PropertyValue> _items;
+    private boolean _cyclic;
+    private int _currentIndex;
+
+    public ListPropertyValue()
+    {
+        super();
+        _cyclic = true;
+        _currentIndex = 0;
+        _items = new ArrayList<PropertyValue>();
+    }
+
+    public synchronized void setItems(List<PropertyValue> items)
+    {
+        _items = new ArrayList<PropertyValue>(items);
+    }
+
+    public synchronized List<PropertyValue> getItems()
+    {
+        return Collections.unmodifiableList(_items);
+    }
+
+    public synchronized void setCyclic(boolean cyclic)
+    {
+        _cyclic = cyclic;
+    }
+
+    public synchronized boolean isCyclic()
+    {
+        return _cyclic;
+    }
+
+    @Override
+    public synchronized Object nextValue()
+    {
+        if (_currentIndex >= _items.size())
+        {
+            if (_cyclic)
+            {
+                _currentIndex = 0;
+            }
+            else
+            {
+                _currentIndex = _items.size() -1;
+            }
+        }
+        Object nextValue = _items.get(_currentIndex);
+        _currentIndex++;
+        return nextValue;
+    }
+
+    @Override
+    public String getDefinition()
+    {
+        return DEF_VALUE;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + _currentIndex;
+        result = prime * result + (_cyclic ? 1231 : 1237);
+        result = prime * result + ((_items == null) ? 0 : _items.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+        {
+            return true;
+        }
+        if (obj == null || !(obj instanceof ListPropertyValue))
+        {
+            return false;
+        }
+        ListPropertyValue other = (ListPropertyValue) obj;
+        if (_cyclic != other._cyclic)
+        {
+            return false;
+        }
+        if (_items == null && other._items != null)
+        {
+             return false;
+        }
+        return _items.equals(other._items);
+    }
+
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/NumericGeneratedPropertySupport.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/NumericGeneratedPropertySupport.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/NumericGeneratedPropertySupport.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/NumericGeneratedPropertySupport.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.client.property;
+
+import java.util.Arrays;
+
+/**
+ * Provides support for numeric generators with lower and upper boundaries.
+ */
+public abstract class NumericGeneratedPropertySupport extends GeneratedPropertySupport
+{
+    public static final Class<?>[] SUPPORTED_TYPES = { double.class, float.class, int.class, long.class, short.class,
+            byte.class };
+
+    private String _type;
+    private double _upper;
+    private double _lower;
+
+
+    public NumericGeneratedPropertySupport()
+    {
+        super();
+        _type = SUPPORTED_TYPES[0].getName();
+        _upper = Double.MAX_VALUE;
+        _lower = 0.0;
+    }
+
+    public synchronized String getType()
+    {
+        return _type;
+    }
+
+    public synchronized double getUpper()
+    {
+        return _upper;
+    }
+
+    public synchronized double getLower()
+    {
+        return _lower;
+    }
+
+    public synchronized void setUpper(double upper)
+    {
+        _upper = upper;
+    }
+
+    public synchronized void setLower(double lower)
+    {
+        _lower = lower;
+    }
+
+    public synchronized void setType(String type)
+    {
+        _type = toClass(type).getName();
+    }
+
+    protected Class<?> toClass(String type)
+    {
+        Class<?> t = null;
+        for (int i = 0; i < SUPPORTED_TYPES.length; i++)
+        {
+            if (SUPPORTED_TYPES[i].getName().equals(type))
+            {
+                t = SUPPORTED_TYPES[i];
+                break;
+            }
+        }
+        if (t == null)
+        {
+            throw new IllegalArgumentException("Type " + type + " is not supported: "
+                    + Arrays.toString(SUPPORTED_TYPES));
+        }
+        return t;
+    }
+
+    @Override
+    public Object nextValue()
+    {
+        double result = nextDouble();
+        return doubleToNumber(result, toClass(_type));
+    }
+
+    protected Number doubleToNumber(double value, Class<?> targetType)
+    {
+        Number result = null;
+        if (targetType == double.class)
+        {
+            result = new Double(value);
+        }
+        else if (targetType == float.class)
+        {
+            result = new Float(value);
+        }
+        else if (targetType == int.class)
+        {
+            result = new Integer((int) value);
+        }
+        else if (targetType == long.class)
+        {
+            result = new Long((long) value);
+        }
+        else if (targetType == short.class)
+        {
+            result = new Short((short) value);
+        }
+        else if (targetType == byte.class)
+        {
+            result = new Byte((byte) value);
+        }
+        else
+        {
+            throw new IllegalArgumentException("Type " + targetType + " is not supported: "
+                    + Arrays.toString(SUPPORTED_TYPES));
+        }
+        return result;
+    }
+
+    protected abstract double nextDouble();
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = super.hashCode();
+        long temp;
+        temp = Double.doubleToLongBits(_lower);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        result = prime * result + ((_type == null) ? 0 : _type.hashCode());
+        temp = Double.doubleToLongBits(_upper);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+        {
+            return true;
+        }
+        if (obj == null || !(obj instanceof NumericGeneratedPropertySupport))
+        {
+            return false;
+        }
+        NumericGeneratedPropertySupport other = (NumericGeneratedPropertySupport) obj;
+        if (Double.doubleToLongBits(_lower) != Double.doubleToLongBits(other._lower)
+                || Double.doubleToLongBits(_upper) != Double.doubleToLongBits(other._upper))
+        {
+            return false;
+        }
+        if (_type == null && other._type != null)
+        {
+            return false;
+        }
+        else if (!_type.equals(other._type))
+        {
+            return false;
+        }
+        return true;
+    }
+
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/PropertyValue.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/PropertyValue.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/PropertyValue.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/PropertyValue.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.client.property;
+
+/**
+ * Provides operations to get a message property value.
+ */
+public interface PropertyValue
+{
+    public Object getValue();
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/PropertyValueFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/PropertyValueFactory.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/PropertyValueFactory.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/PropertyValueFactory.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.client.property;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.qpid.disttest.DistributedTestException;
+
+/**
+ * Creates property value instances using given alias (type) value.
+ */
+public class PropertyValueFactory
+{
+    public PropertyValue createPropertyValue(String type)
+    {
+        try
+        {
+            return (PropertyValue)getPropertyValueClass(type).newInstance();
+        }
+        catch(Exception e)
+        {
+            throw new DistributedTestException("Unable to create a generator for a type:" + type, e);
+        }
+    }
+
+    public Class<?> getPropertyValueClass(String type) throws ClassNotFoundException
+    {
+        String className = "org.apache.qpid.disttest.client.property." + StringUtils.capitalize(type) + "PropertyValue";
+        return Class.forName(className);
+    }
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/RandomPropertyValue.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/RandomPropertyValue.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/RandomPropertyValue.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/RandomPropertyValue.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.client.property;
+
+/**
+ * Generates random property values in a given lower and upper boundaries.
+ */
+public class RandomPropertyValue extends NumericGeneratedPropertySupport
+{
+    public static final String DEF_VALUE = "random";
+
+    public RandomPropertyValue()
+    {
+        super();
+    }
+
+    @Override
+    protected double nextDouble()
+    {
+        double lower = getLower();
+        double upper = getUpper();
+        return lower + Math.random() * (upper - lower);
+    }
+
+    @Override
+    public String getDefinition()
+    {
+        return DEF_VALUE;
+    }
+
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/RangePropertyValue.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/RangePropertyValue.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/RangePropertyValue.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/RangePropertyValue.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.client.property;
+
+/**
+ * Generates property values from a range with given lower and upper boundaries.
+ */
+public class RangePropertyValue extends NumericGeneratedPropertySupport
+{
+    public static final String DEF_VALUE = "range";
+    private double _step;
+    private double _currentValue;
+    private boolean _cyclic;
+
+    public RangePropertyValue()
+    {
+        super();
+        _cyclic = true;
+        _currentValue = 0.0;
+        _step = 1.0;
+    }
+
+    public synchronized double getStep()
+    {
+        return _step;
+    }
+
+    public synchronized boolean isCyclic()
+    {
+        return _cyclic;
+    }
+
+    public synchronized void setCyclic(boolean cyclic)
+    {
+        _cyclic = cyclic;
+    }
+
+    public synchronized void setStep(double step)
+    {
+        _step = step;
+    }
+
+    @Override
+    public synchronized double nextDouble()
+    {
+        double result = 0.0;
+        double lower = getLower();
+        double upper = getUpper();
+        if (_currentValue < lower)
+        {
+            _currentValue = lower;
+        }
+        else if (_currentValue > upper)
+        {
+            if (_cyclic)
+            {
+                _currentValue = lower;
+            }
+            else
+            {
+                _currentValue = upper;
+            }
+        }
+        result = _currentValue;
+        _currentValue += _step;
+        return result;
+    }
+
+    @Override
+    public String getDefinition()
+    {
+        return DEF_VALUE;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = super.hashCode();
+        long temp;
+        temp = Double.doubleToLongBits(_currentValue);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        result = prime * result + (_cyclic ? 1231 : 1237);
+        temp = Double.doubleToLongBits(_step);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+        {
+            return true;
+        }
+        if (!(obj instanceof RangePropertyValue))
+        {
+            return false;
+        }
+        if (!super.equals(obj))
+        {
+            return false;
+        }
+        RangePropertyValue other = (RangePropertyValue) obj;
+        if (Double.doubleToLongBits(_currentValue) != Double.doubleToLongBits(other._currentValue)
+                || Double.doubleToLongBits(_step) != Double.doubleToLongBits(other._step) || _cyclic != other._cyclic)
+        {
+            return false;
+        }
+
+        return true;
+    }
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/SimplePropertyValue.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/SimplePropertyValue.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/SimplePropertyValue.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/client/property/SimplePropertyValue.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.client.property;
+
+/**
+ * Simple property value holder for a constant properties.
+ */
+public class SimplePropertyValue implements PropertyValue
+{
+    private Object _value;
+
+    public SimplePropertyValue()
+    {
+        super();
+    }
+
+    public SimplePropertyValue(Object value)
+    {
+        super();
+        this._value = value;
+    }
+
+    @Override
+    public Object getValue()
+    {
+        return _value;
+    }
+
+    @Override
+    public String toString()
+    {
+        return "SimplePropertyValue [value=" + _value + "]";
+    }
+
+    @Override
+    public int hashCode()
+    {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((_value == null) ? 0 : _value.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj)
+    {
+        if (this == obj)
+        {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass())
+        {
+            return false;
+        }
+        SimplePropertyValue other = (SimplePropertyValue) obj;
+        if (_value == null && other._value != null)
+        {
+             return false;
+        }
+        return _value.equals(other._value);
+    }
+
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ClientRegistry.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ClientRegistry.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ClientRegistry.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ClientRegistry.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.controller;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ConcurrentSkipListSet;
+
+import org.apache.qpid.disttest.DistributedTestException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ClientRegistry
+{
+    private static final Logger LOGGER = LoggerFactory.getLogger(ClientRegistry.class);
+
+    private final Set<String> _registeredClientNames = new ConcurrentSkipListSet<String>();
+
+    public void registerClient(String clientName)
+    {
+        final boolean alreadyContainsClient = !_registeredClientNames.add(clientName);
+        if (alreadyContainsClient)
+        {
+            throw new DistributedTestException("Duplicate client name " + clientName);
+        }
+
+        LOGGER.info("Client registered: " + clientName);
+    }
+
+    public Collection<String> getClients()
+    {
+        return Collections.unmodifiableSet(_registeredClientNames);
+    }
+
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/CommandForClient.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/CommandForClient.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/CommandForClient.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/CommandForClient.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.controller;
+
+import org.apache.qpid.disttest.message.Command;
+
+public class CommandForClient
+{
+    private String _clientName;
+    private Command _command;
+
+    public CommandForClient(String clientName, Command command)
+    {
+        _clientName = clientName;
+        _command = command;
+    }
+
+    public String getClientName()
+    {
+        return _clientName;
+    }
+
+    public Command getCommand()
+    {
+        return _command;
+    }
+
+
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/CommandListener.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/CommandListener.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/CommandListener.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/CommandListener.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.controller;
+
+import org.apache.qpid.disttest.message.Command;
+
+public interface CommandListener
+{
+
+    public abstract void processCommand(Command command);
+
+    public boolean supports(Command command);
+
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/Controller.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/Controller.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/Controller.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/Controller.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,227 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.controller;
+
+import java.util.Collection;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.qpid.disttest.DistributedTestException;
+import org.apache.qpid.disttest.controller.config.Config;
+import org.apache.qpid.disttest.controller.config.TestInstance;
+import org.apache.qpid.disttest.jms.ControllerJmsDelegate;
+import org.apache.qpid.disttest.message.Command;
+import org.apache.qpid.disttest.message.CommandType;
+import org.apache.qpid.disttest.message.RegisterClientCommand;
+import org.apache.qpid.disttest.message.Response;
+import org.apache.qpid.disttest.message.StopClientCommand;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Controller
+{
+    private static final Logger LOGGER = LoggerFactory.getLogger(Controller.class);
+
+    private final long _registrationTimeout;
+    private final long _commandResponseTimeout;
+
+    private final ControllerJmsDelegate _jmsDelegate;
+
+    private volatile CountDownLatch _clientRegistrationLatch;
+    private volatile CountDownLatch _stopClientsResponseLatch = null;
+
+    private Config _config;
+    private TestRunnerFactory _testRunnerFactory;
+    private ClientRegistry _clientRegistry;
+
+    private long _testResultTimeout = TestRunner.WAIT_FOREVER;
+
+    public Controller(final ControllerJmsDelegate jmsDelegate, long registrationTimeout, long commandResponseTimeout)
+    {
+        _jmsDelegate = jmsDelegate;
+        _registrationTimeout = registrationTimeout;
+        _commandResponseTimeout = commandResponseTimeout;
+        _testRunnerFactory = new TestRunnerFactory();
+        _clientRegistry = new ClientRegistry();
+    }
+
+    public void setConfig(Config config)
+    {
+        _config = config;
+        validateConfiguration();
+        int numberOfClients = config.getTotalNumberOfClients();
+        _clientRegistrationLatch = new CountDownLatch(numberOfClients);
+
+        _jmsDelegate.addCommandListener(new RegisterClientCommandListener());
+        _jmsDelegate.addCommandListener(new StopClientResponseListener());
+        _jmsDelegate.start();
+    }
+
+
+    public void awaitClientRegistrations()
+    {
+        LOGGER.info("Awaiting client registration");
+        awaitLatch(_clientRegistrationLatch, _registrationTimeout, "Timed out waiting for registrations. Expecting %d more registrations");
+    }
+
+    private void validateConfiguration()
+    {
+        if (_config == null || _config.getTotalNumberOfClients() == 0)
+        {
+            throw new DistributedTestException("No controller config or no clients specified in test config");
+        }
+    }
+
+    private void awaitLatch(CountDownLatch latch, long timeout, String messageWithOneDecimalPlaceholder)
+    {
+        try
+        {
+            final boolean countedDownOK = latch.await(timeout, TimeUnit.MILLISECONDS);
+            if (!countedDownOK)
+            {
+                final long latchCount = latch.getCount();
+                String formattedMessage = String.format(messageWithOneDecimalPlaceholder, latchCount);
+                throw new DistributedTestException(formattedMessage);
+            }
+        }
+        catch (final InterruptedException e)
+        {
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    public void registerClient(final RegisterClientCommand registrationCommand)
+    {
+        final String clientName = registrationCommand.getClientName();
+
+        _clientRegistry.registerClient(clientName);
+        _jmsDelegate.registerClient(registrationCommand);
+
+        _clientRegistrationLatch.countDown();
+        LOGGER.info("Counted down latch for client: " + clientName + " latch count=" + _clientRegistrationLatch.getCount());
+    }
+
+    void processStopClientResponse(final Response response)
+    {
+        _stopClientsResponseLatch.countDown();
+        if (response.hasError())
+        {
+            LOGGER.error("Client " + response.getRegisteredClientName() + " reported exception in response to command : " +
+                    response.getErrorMessage());
+        }
+    }
+
+    public void stopAllRegisteredClients()
+    {
+        Collection<String> registeredClients = _clientRegistry.getClients();
+
+        LOGGER.info("Stopping all clients");
+        _stopClientsResponseLatch = new CountDownLatch(registeredClients.size());
+        Command command = new StopClientCommand();
+        for (final String clientName : registeredClients)
+        {
+            _jmsDelegate.sendCommandToClient(clientName, command);
+        }
+
+        awaitLatch(_stopClientsResponseLatch, _commandResponseTimeout, "Timed out waiting for stop command responses. Expecting %d more responses.");
+
+        LOGGER.info("Stopped all clients");
+    }
+
+
+    public ResultsForAllTests runAllTests()
+    {
+        LOGGER.info("Running all tests");
+
+        ResultsForAllTests resultsForAllTests = new ResultsForAllTests();
+
+        for (TestInstance testInstance : _config.getTests())
+        {
+
+            ParticipatingClients participatingClients = new ParticipatingClients(_clientRegistry, testInstance.getClientNames());
+
+            LOGGER.info("Running test " + testInstance + ". Participating clients: " + participatingClients.getRegisteredNames());
+            TestRunner runner = _testRunnerFactory.createTestRunner(participatingClients,
+                                                                    testInstance,
+                                                                    _jmsDelegate,
+                                                                    _commandResponseTimeout,
+                                                                    _testResultTimeout);
+
+            TestResult testResult = runner.run();
+            LOGGER.info("Finished test " + testInstance);
+
+            resultsForAllTests.add(testResult);
+        }
+
+        return resultsForAllTests;
+    }
+
+    private final class StopClientResponseListener implements CommandListener
+    {
+        @Override
+        public boolean supports(Command command)
+        {
+            return command.getType() == CommandType.RESPONSE && ((Response)command).getInReplyToCommandType() == CommandType.STOP_CLIENT;
+        }
+
+        @Override
+        public void processCommand(Command command)
+        {
+            processStopClientResponse((Response)command);
+        }
+    }
+
+    private final class RegisterClientCommandListener implements
+            CommandListener
+    {
+        @Override
+        public boolean supports(Command command)
+        {
+            return command.getType() == CommandType.REGISTER_CLIENT;
+        }
+
+        @Override
+        public void processCommand(Command command)
+        {
+            registerClient((RegisterClientCommand)command);
+        }
+    }
+
+    public void setTestResultTimeout(final long testResultTimeout)
+    {
+        _testResultTimeout = testResultTimeout;
+
+    }
+
+    void setClientRegistry(ClientRegistry clientRegistry)
+    {
+        _clientRegistry = clientRegistry;
+
+    }
+
+    void setTestRunnerFactory(TestRunnerFactory factory)
+    {
+        if (factory == null)
+        {
+            throw new IllegalArgumentException("TestRunnerFactory cannot be null!");
+        }
+        _testRunnerFactory = factory;
+    }
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ParticipatingClients.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ParticipatingClients.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ParticipatingClients.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ParticipatingClients.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.controller;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.TreeSet;
+
+import org.apache.commons.collections.BidiMap;
+import org.apache.commons.collections.bidimap.DualHashBidiMap;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+
+public class ParticipatingClients
+{
+    private final BidiMap _configuredToRegisteredNameMap;
+
+    public ParticipatingClients(ClientRegistry clientRegistry, List<String> configuredClientNamesForTest)
+    {
+        _configuredToRegisteredNameMap = mapConfiguredToRegisteredClientNames(configuredClientNamesForTest, clientRegistry);
+    }
+
+    public String getRegisteredNameFromConfiguredName(String clientConfiguredName)
+    {
+        String registeredClientName = (String) _configuredToRegisteredNameMap.get(clientConfiguredName);
+        if (registeredClientName == null)
+        {
+            throw new IllegalArgumentException("Unrecognised client configured name " + clientConfiguredName
+                    + " Mapping is " + _configuredToRegisteredNameMap);
+        }
+        return registeredClientName;
+    }
+
+    public String getConfiguredNameFromRegisteredName(String registeredClientName)
+    {
+        String clientConfiguredName = (String) _configuredToRegisteredNameMap.getKey(registeredClientName);
+        if (clientConfiguredName == null)
+        {
+            throw new IllegalArgumentException("Unrecognised client registered name " + registeredClientName
+                    + " Mapping is " + _configuredToRegisteredNameMap);
+        }
+
+        return clientConfiguredName;
+    }
+
+    private BidiMap mapConfiguredToRegisteredClientNames(List<String> configuredClientNamesForTest, ClientRegistry clientRegistry)
+    {
+        BidiMap configuredToRegisteredNameMap = new DualHashBidiMap();
+
+        TreeSet<String> registeredClients = new TreeSet<String>(clientRegistry.getClients());
+        for (String configuredClientName : configuredClientNamesForTest)
+        {
+            String allocatedClientName = registeredClients.pollFirst();
+            if (allocatedClientName == null)
+            {
+                throw new IllegalArgumentException("Too few clients in registry " + clientRegistry + " configured clients " + configuredClientNamesForTest);
+            }
+            configuredToRegisteredNameMap.put(configuredClientName, allocatedClientName);
+        }
+
+        return configuredToRegisteredNameMap;
+    }
+
+    @SuppressWarnings("unchecked")
+    public Collection<String> getRegisteredNames()
+    {
+        return _configuredToRegisteredNameMap.values();
+    }
+
+    @Override
+    public String toString()
+    {
+        return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+            .append("configuredToRegisteredNameMap", _configuredToRegisteredNameMap).toString();
+    }
+
+
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ResultsForAllTests.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ResultsForAllTests.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ResultsForAllTests.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/ResultsForAllTests.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.controller;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.qpid.disttest.results.aggregation.ITestResult;
+
+public class ResultsForAllTests
+{
+    private List<ITestResult> _results = new ArrayList<ITestResult>();
+    private boolean _hasErrors;
+
+    public List<ITestResult> getTestResults()
+    {
+        return _results;
+    }
+
+    public void add(ITestResult testResult)
+    {
+        _results.add(testResult);
+        if(testResult.hasErrors())
+        {
+            _hasErrors = true;
+        }
+    }
+
+    public boolean hasErrors()
+    {
+        return _hasErrors;
+    }
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestResult.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestResult.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestResult.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestResult.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.controller;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.qpid.disttest.message.ParticipantResult;
+import org.apache.qpid.disttest.results.aggregation.ITestResult;
+
+public class TestResult implements ITestResult
+{
+    private final SortedSet<ParticipantResult> _participantResults = Collections.synchronizedSortedSet(
+            new TreeSet<ParticipantResult>(ParticipantResult.PARTICIPANT_NAME_COMPARATOR));
+
+    private boolean _hasErrors;
+    private String _name;
+
+    public TestResult(String name)
+    {
+        _name = name;
+    }
+
+    @Override
+    public List<ParticipantResult> getParticipantResults()
+    {
+        List<ParticipantResult> list = new ArrayList<ParticipantResult>(_participantResults);
+        return Collections.unmodifiableList(list);
+    }
+
+    public void addParticipantResult(ParticipantResult participantResult)
+    {
+        _participantResults.add(participantResult);
+        if(participantResult.hasError())
+        {
+            _hasErrors = true;
+        }
+    }
+
+    @Override
+    public boolean hasErrors()
+    {
+        return _hasErrors;
+    }
+
+    @Override
+    public String getName()
+    {
+        return _name;
+    }
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestRunner.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestRunner.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestRunner.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestRunner.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,307 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.controller;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.qpid.disttest.DistributedTestException;
+import org.apache.qpid.disttest.controller.config.QueueConfig;
+import org.apache.qpid.disttest.controller.config.TestInstance;
+import org.apache.qpid.disttest.jms.ControllerJmsDelegate;
+import org.apache.qpid.disttest.message.Command;
+import org.apache.qpid.disttest.message.CommandType;
+import org.apache.qpid.disttest.message.ParticipantResult;
+import org.apache.qpid.disttest.message.Response;
+import org.apache.qpid.disttest.message.StartTestCommand;
+import org.apache.qpid.disttest.message.TearDownTestCommand;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TestRunner
+{
+    private static final Logger LOGGER = LoggerFactory.getLogger(TestRunner.class);
+
+    private static final long PARTICIPANT_RESULTS_LOG_INTERVAL = 60000;
+    public static final long WAIT_FOREVER = -1;
+
+    private final long _commandResponseTimeout;
+
+    private final Set<CommandType> _setOfResponsesToExpect = Collections.synchronizedSet(new HashSet<CommandType>());
+
+    private final ParticipatingClients _participatingClients;
+
+    private final TestInstance _testInstance;
+    private ControllerJmsDelegate _jmsDelegate;
+
+    private volatile CountDownLatch _commandResponseLatch = null;
+    private final CountDownLatch _testResultsLatch;
+    private final TestResult _testResult;
+
+    /** Length of time to await test results or {@value #WAIT_FOREVER} */
+    private final long _testResultTimeout;
+
+
+    public TestRunner(ParticipatingClients participatingClients, TestInstance testInstance, ControllerJmsDelegate jmsDelegate, long commandResponseTimeout, long testResultTimeout)
+    {
+        _participatingClients = participatingClients;
+        _testInstance = testInstance;
+        _jmsDelegate = jmsDelegate;
+        _commandResponseTimeout = commandResponseTimeout;
+        _testResultsLatch = new CountDownLatch(testInstance.getTotalNumberOfParticipants());
+        _testResultTimeout = testResultTimeout;
+        _testResult = new TestResult(testInstance.getName());
+    }
+
+    public TestResult run()
+    {
+        final ParticipantResultListener participantResultListener = new ParticipantResultListener();
+        TestCommandResponseListener testCommandResponseListener = new TestCommandResponseListener();
+
+        try
+        {
+            _jmsDelegate.addCommandListener(testCommandResponseListener);
+            _jmsDelegate.addCommandListener(participantResultListener);
+
+            runParts();
+
+            return _testResult;
+        }
+        finally
+        {
+            _jmsDelegate.removeCommandListener(participantResultListener);
+            _jmsDelegate.removeCommandListener(testCommandResponseListener);
+        }
+    }
+
+    private void runParts()
+    {
+        boolean queuesCreated = false;
+        try
+        {
+            createQueues();
+            queuesCreated = true;
+            sendTestSetupCommands();
+            awaitCommandResponses();
+            sendCommandToParticipatingClients(new StartTestCommand());
+            awaitCommandResponses();
+
+            awaitTestResults();
+
+            sendCommandToParticipatingClients(new TearDownTestCommand());
+            awaitCommandResponses();
+        }
+        finally
+        {
+            if (queuesCreated)
+            {
+                deleteQueues();
+            }
+        }
+    }
+
+    void createQueues()
+    {
+        List<QueueConfig> queues = _testInstance.getQueues();
+        if (!queues.isEmpty())
+        {
+            _jmsDelegate.createQueues(queues);
+        }
+    }
+
+    void sendTestSetupCommands()
+    {
+        List<CommandForClient> commandsForAllClients = _testInstance.createCommands();
+        _commandResponseLatch = new CountDownLatch(commandsForAllClients.size());
+        for (CommandForClient commandForClient : commandsForAllClients)
+        {
+            String configuredClientName = commandForClient.getClientName();
+            String registeredClientName = _participatingClients.getRegisteredNameFromConfiguredName(configuredClientName);
+
+            Command command = commandForClient.getCommand();
+            sendCommandInternal(registeredClientName, command);
+        }
+    }
+
+    void awaitCommandResponses()
+    {
+        awaitLatch(_commandResponseLatch, _commandResponseTimeout, "Timed out waiting for command responses. Expecting %d more responses.");
+    }
+
+
+    void processCommandResponse(final Response response)
+    {
+        if (LOGGER.isDebugEnabled())
+        {
+            LOGGER.debug("Received response for command " + response);
+        }
+
+        _commandResponseLatch.countDown();
+        checkForResponseError(response);
+    }
+
+
+    void awaitTestResults()
+    {
+        long timeout = _testResultTimeout;
+        DistributedTestException lastException = null;
+
+        boolean waitForever = _testResultTimeout == WAIT_FOREVER;
+        final long interval = waitForever ? PARTICIPANT_RESULTS_LOG_INTERVAL : Math.min(PARTICIPANT_RESULTS_LOG_INTERVAL, _testResultTimeout);
+
+        while(_testResultsLatch.getCount() > 0 && (waitForever || timeout > 0))
+        {
+            try
+            {
+                awaitLatch(_testResultsLatch, interval, "Waiting for participant results... Expecting %d more responses.");
+            }
+            catch (DistributedTestException e)
+            {
+                lastException = e;
+                LOGGER.info(e.getMessage());
+            }
+
+            if (!waitForever)
+            {
+                timeout =- interval;
+            }
+        }
+
+        if (_testResultsLatch.getCount() > 0)
+        {
+            throw lastException;
+        }
+    }
+
+    void deleteQueues()
+    {
+        List<QueueConfig> queues = _testInstance.getQueues();
+        if (!queues.isEmpty())
+        {
+            _jmsDelegate.deleteQueues(queues);
+        }
+    }
+
+    void sendCommandToParticipatingClients(final Command command)
+    {
+        Collection<String> participatingRegisteredClients = _participatingClients.getRegisteredNames();
+        _commandResponseLatch = new CountDownLatch(participatingRegisteredClients.size());
+        for (final String clientName : participatingRegisteredClients)
+        {
+            sendCommandInternal(clientName, command);
+        }
+    }
+
+    public void processParticipantResult(ParticipantResult result)
+    {
+        setOriginalTestDetailsOn(result);
+
+        _testResult.addParticipantResult(result);
+        LOGGER.info("Received result " + result);
+
+        _testResultsLatch.countDown();
+        checkForResponseError(result);
+    }
+
+    private void setOriginalTestDetailsOn(ParticipantResult result)
+    {
+        // Client knows neither the configured client name nor test name
+        String registeredClientName = result.getRegisteredClientName();
+        String configuredClient = _participatingClients.getConfiguredNameFromRegisteredName(registeredClientName);
+
+        result.setConfiguredClientName(configuredClient);
+        result.setTestName(_testInstance.getName());
+        result.setIterationNumber(_testInstance.getIterationNumber());
+    }
+
+    private void sendCommandInternal(String registeredClientName, Command command)
+    {
+        _setOfResponsesToExpect.add(command.getType());
+        _jmsDelegate.sendCommandToClient(registeredClientName, command);
+    }
+
+    private void awaitLatch(CountDownLatch latch, long timeout, String messageWithOneDecimalPlaceholder)
+    {
+        try
+        {
+            final boolean countedDownOK = latch.await(timeout, TimeUnit.MILLISECONDS);
+            if (!countedDownOK)
+            {
+                final long latchCount = latch.getCount();
+                String formattedMessage = String.format(messageWithOneDecimalPlaceholder, latchCount);
+                throw new DistributedTestException(formattedMessage);
+            }
+        }
+        catch (final InterruptedException e)
+        {
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    private void checkForResponseError(final Response response)
+    {
+        if (response.hasError())
+        {
+            LOGGER.error("Client " + response.getRegisteredClientName() + " reported error " + response);
+        }
+    }
+
+    final class ParticipantResultListener implements CommandListener
+    {
+        @Override
+        public boolean supports(Command command)
+        {
+            return command instanceof ParticipantResult;
+        }
+
+        @Override
+        public void processCommand(Command command)
+        {
+            processParticipantResult((ParticipantResult) command);
+
+        }
+    }
+
+    final class TestCommandResponseListener implements CommandListener
+    {
+        @Override
+        public void processCommand(Command command)
+        {
+            processCommandResponse((Response)command);
+        }
+
+        @Override
+        public boolean supports(Command command)
+        {
+            CommandType type = command.getType();
+            if (type == CommandType.RESPONSE)
+            {
+                Response response = (Response)command;
+                return _setOfResponsesToExpect.contains(response.getInReplyToCommandType());
+            }
+            return false;
+        }
+    }
+
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestRunnerFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestRunnerFactory.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestRunnerFactory.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/TestRunnerFactory.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.controller;
+
+import org.apache.qpid.disttest.controller.config.TestInstance;
+import org.apache.qpid.disttest.jms.ControllerJmsDelegate;
+
+public class TestRunnerFactory
+{
+    public TestRunner createTestRunner(ParticipatingClients participatingClients, TestInstance testInstance, ControllerJmsDelegate jmsDelegate, long commandResponseTimeout, long testResultTimeout)
+    {
+        return new TestRunner(participatingClients, testInstance, jmsDelegate, commandResponseTimeout, testResultTimeout);
+    }
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ClientConfig.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ClientConfig.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ClientConfig.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ClientConfig.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.controller.config;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.qpid.disttest.controller.CommandForClient;
+import org.apache.qpid.disttest.message.Command;
+
+public class ClientConfig
+{
+    /*
+     * TODO add this field when repeating groups of clients need to be used. Talk to Phil and Keith!
+     * private int _instances;
+    */
+
+    private List<ConnectionConfig> _connections;
+    private List<MessageProviderConfig> _messageProviders;
+    private String _name;
+
+    public ClientConfig()
+    {
+        _name = null;
+        _connections = Collections.emptyList();
+        _messageProviders = Collections.emptyList();
+    }
+
+    public ClientConfig(String name, ConnectionConfig... connections)
+    {
+        this(name,  Arrays.asList(connections), null);
+    }
+
+    public ClientConfig(String name, List<ConnectionConfig> connections, List<MessageProviderConfig> messageProviders)
+    {
+        _name = name;
+        _connections = connections;
+        if (messageProviders == null)
+        {
+            _messageProviders = Collections.emptyList();
+        }
+        else
+        {
+            _messageProviders = messageProviders;
+        }
+    }
+
+    public String getName()
+    {
+        return _name;
+    }
+
+    public List<ConnectionConfig> getConnections()
+    {
+        return Collections.unmodifiableList(_connections);
+    }
+
+    public List<CommandForClient> createCommands()
+    {
+        List<CommandForClient> commandsForClient = new ArrayList<CommandForClient>();
+
+        for (MessageProviderConfig messageProvider : _messageProviders)
+        {
+            Command command = messageProvider.createCommand();
+            commandsForClient.add(new CommandForClient(_name, command));
+        }
+        for (ConnectionConfig connection : _connections)
+        {
+            List<Command> commands = connection.createCommands();
+            for (Command command : commands)
+            {
+                commandsForClient.add(new CommandForClient(_name, command));
+            }
+        }
+        return commandsForClient;
+    }
+
+    public int getTotalNumberOfParticipants()
+    {
+        int numOfParticipants = 0;
+        for (ConnectionConfig connection : _connections)
+        {
+            numOfParticipants = numOfParticipants + connection.getTotalNumberOfParticipants();
+        }
+        return numOfParticipants;
+    }
+
+    public List<MessageProviderConfig> getMessageProviders()
+    {
+        return Collections.unmodifiableList(_messageProviders);
+    }
+
+
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/Config.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/Config.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/Config.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/Config.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.controller.config;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class Config
+{
+    private List<TestConfig> _tests;
+
+    public Config()
+    {
+        super();
+        _tests = Collections.emptyList();
+    }
+
+    public Config(TestConfig... tests)
+    {
+        _tests = Arrays.asList(tests);
+    }
+
+    public List<TestInstance> getTests()
+    {
+        List<TestInstance> testInstances = new ArrayList<TestInstance>();
+        for (TestConfig testConfig : _tests)
+        {
+            int iterationNumber = 0;
+
+            List<IterationValue> iterationValues = testConfig.getIterationValues();
+            if(iterationValues.isEmpty())
+            {
+               testInstances.add(new TestInstance(testConfig));
+            }
+            else
+            {
+                for (IterationValue iterationValue : iterationValues)
+                {
+                    testInstances.add(new TestInstance(testConfig, iterationNumber, iterationValue));
+                    iterationNumber++;
+                }
+            }
+        }
+
+        return Collections.unmodifiableList(testInstances);
+    }
+
+    List<TestConfig> getTestConfigs()
+    {
+        return Collections.unmodifiableList(_tests);
+    }
+
+    public int getTotalNumberOfClients()
+    {
+        int numberOfClients = 0;
+        for (TestConfig testConfig : _tests)
+        {
+            numberOfClients = Math.max(testConfig.getTotalNumberOfClients(), numberOfClients);
+        }
+        return numberOfClients;
+    }
+
+}

Added: qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ConfigReader.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ConfigReader.java?rev=1309918&view=auto
==============================================================================
--- qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ConfigReader.java (added)
+++ qpid/trunk/qpid/java/perftests/src/main/java/org/apache/qpid/disttest/controller/config/ConfigReader.java Thu Apr  5 16:04:10 2012
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.qpid.disttest.controller.config;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.Reader;
+
+import org.apache.qpid.disttest.client.property.PropertyValue;
+import org.apache.qpid.disttest.json.PropertyValueAdapter;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class ConfigReader
+{
+
+    public Config getConfigFromFile(String fileName) throws FileNotFoundException
+    {
+        FileReader reader = new FileReader(fileName);
+
+        Config config = readConfig(reader);
+        return config;
+    }
+
+    public Config readConfig(Reader reader)
+    {
+        Gson gson = new GsonBuilder()
+            .registerTypeAdapter(PropertyValue.class, new PropertyValueAdapter())
+            .create();
+        Config config = gson.fromJson(reader, Config.class);
+        return config;
+    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org