summaryrefslogtreecommitdiff
path: root/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/LocalCircuitFactory.java
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/java/systests/src/main/java/org/apache/qpid/test/framework/LocalCircuitFactory.java')
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/test/framework/LocalCircuitFactory.java316
1 files changed, 316 insertions, 0 deletions
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/LocalCircuitFactory.java b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/LocalCircuitFactory.java
new file mode 100644
index 0000000000..ec70759cf7
--- /dev/null
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/test/framework/LocalCircuitFactory.java
@@ -0,0 +1,316 @@
+/*
+ *
+ * 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.test.framework;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.test.framework.localcircuit.LocalCircuitImpl;
+import org.apache.qpid.test.framework.localcircuit.LocalPublisherImpl;
+import org.apache.qpid.test.framework.localcircuit.LocalReceiverImpl;
+import org.apache.qpid.test.framework.sequencers.CircuitFactory;
+import org.apache.qpid.test.utils.ConversationFactory;
+
+import org.apache.qpid.junit.extensions.util.ParsedProperties;
+
+import javax.jms.*;
+
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * LocalCircuitFactory is a circuit factory that creates test circuits with publishing and receiving ends rooted
+ * on the same JVM. The ends of the circuit are presented as {@link Publisher} and {@link Receiver} interfaces, which
+ * in turn provide methods to apply assertions to the circuit. The creation of the circuit ends, and the presentation
+ * of the ends as publisher/receiver interfaces, are designed to be overriden, so that circuits and assertions that
+ * use messaging features not available in JMS can be written. This provides an extension point for writing tests
+ * against proprietary features of JMS implementations.
+ *
+ * <p/><table id="crc"><caption>CRC Card</caption>
+ * <tr><th> Responsibilities <th> Collaborations
+ * <tr><td> Provide a standard test procedure over a test circuit.
+ * <tr><td> Construct test circuits appropriate to a tests context.
+ * </table>
+ */
+public class LocalCircuitFactory implements CircuitFactory
+{
+ /** Used for debugging. */
+ private static final Logger log = Logger.getLogger(LocalCircuitFactory.class);
+
+ /** Used to create unique destination names for each test. */
+ protected static AtomicLong uniqueDestsId = new AtomicLong();
+
+ /**
+ * Holds a test coordinating conversation with the test clients. This should consist of assigning the test roles,
+ * begining the test and gathering the test reports from the participants.
+ *
+ * @param testCircuit The test circuit.
+ * @param assertions The list of assertions to apply to the test circuit.
+ * @param testProperties The test case definition.
+ */
+ public void sequenceTest(Circuit testCircuit, List<Assertion> assertions, Properties testProperties)
+ {
+ if (testCircuit != null)
+ {
+ FrameworkBaseCase.assertNoFailures(testCircuit.test(1, assertions));
+ }
+ }
+
+ /**
+ * Creates a test circuit for the test, configered by the test parameters specified.
+ *
+ * @param testProperties The test parameters.
+ *
+ * @return A test circuit.
+ */
+ public Circuit createCircuit(Connection connection, ParsedProperties testProperties)
+ {
+ Circuit result;
+
+ // Cast the test properties into a typed interface for convenience.
+ MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProperties);
+
+ // Create a standard publisher/receivers test client pair on a shared connection, individual sessions.
+ try
+ {
+ // Get a unique offset to append to destination names to make them unique to the connection.
+ long uniqueId = uniqueDestsId.incrementAndGet();
+
+ // Add the connection exception listener to assert on exception conditions with.
+ // ExceptionMonitor exceptionMonitor = new ExceptionMonitor();
+ // connection.setExceptionListener(exceptionMonitor);
+
+ // Set up the publisher.
+ CircuitEndBase publisherEnd = createPublisherCircuitEnd(connection, props, uniqueId);
+
+ // Set up the receiver.
+ CircuitEndBase receiverEnd = createReceiverCircuitEnd(connection, props, uniqueId);
+
+ // Start listening for incoming messages.
+ connection.start();
+
+ // Package everything up.
+ LocalPublisherImpl publisher = createPublisherFromCircuitEnd(publisherEnd);
+ LocalReceiverImpl receiver = createReceiverFromCircuitEnd(receiverEnd);
+
+ result = new LocalCircuitImpl(testProperties, publisher, receiver, connection, publisher.getExceptionMonitor());
+ }
+ catch (JMSException e)
+ {
+ throw new RuntimeException("Could not create publisher/receivers pair due to a JMSException.", e);
+ }
+
+ return result;
+ }
+
+ /**
+ * Creates a local {@link Receiver} from a {@link CircuitEnd}. Sub-classes may override this to provide more
+ * specialized receivers if necessary.
+ *
+ * @param receiverEnd The receiving circuit end.
+ *
+ * @return A {@link Receiver}.
+ */
+ protected LocalReceiverImpl createReceiverFromCircuitEnd(CircuitEndBase receiverEnd)
+ {
+ return new LocalReceiverImpl(receiverEnd);
+ }
+
+ /**
+ * Creates a local {@link Publisher} from a {@link CircuitEnd}. Sub-classes may override this to provide more
+ * specialized receivers if necessary.
+ *
+ * @param publisherEnd The publishing circuit end.
+ *
+ * @return A {@link Receiver}.
+ */
+ protected LocalPublisherImpl createPublisherFromCircuitEnd(CircuitEndBase publisherEnd)
+ {
+ return new LocalPublisherImpl(publisherEnd);
+ }
+
+ /**
+ * Builds a circuit end suitable for the publishing side of a test circuit, from standard test parameters.
+ *
+ * @param connection The connection to build the circuit end on.
+ * @param testProps The test parameters to configure the circuit end construction.
+ * @param uniqueId A unique number to being numbering destinations from, to make this circuit unique.
+ *
+ * @return A circuit end suitable for the publishing side of a test circuit.
+ *
+ * @throws JMSException Any underlying JMSExceptions are allowed to fall through and fail the creation.
+ */
+ public CircuitEndBase createPublisherCircuitEnd(Connection connection, ParsedProperties testProps, long uniqueId)
+ throws JMSException
+ {
+ log.debug(
+ "public CircuitEndBase createPublisherCircuitEnd(Connection connection, ParsedProperties testProps, long uniqueId = "
+ + uniqueId + "): called");
+
+ // Cast the test properties into a typed interface for convenience.
+ MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProps);
+
+ // Check that the test properties do not contain AMQP/Qpid specific settings, and fail if they do.
+ if (props.getImmediate() || props.getMandatory())
+ {
+ throw new RuntimeException(
+ "Cannot create a pure JMS circuit as the test properties require AMQP specific options.");
+ }
+
+ Session session = connection.createSession(props.getPublisherTransacted(), props.getAckMode());
+
+ Destination destination =
+ props.getPubsub() ? session.createTopic(props.getSendDestinationNameRoot() + "_" + uniqueId)
+ : session.createQueue(props.getSendDestinationNameRoot() + "_" + uniqueId);
+
+ MessageProducer producer = props.getPublisherProducerBind() ? session.createProducer(destination) : null;
+
+ MessageConsumer consumer =
+ props.getPublisherConsumerBind()
+ ? session.createConsumer(session.createQueue(props.getReceiveDestinationNameRoot() + "_" + uniqueId)) : null;
+
+ MessageMonitor messageMonitor = new MessageMonitor();
+
+ if (consumer != null)
+ {
+ consumer.setMessageListener(messageMonitor);
+ }
+
+ ExceptionMonitor exceptionMonitor = new ExceptionMonitor();
+ connection.setExceptionListener(exceptionMonitor);
+
+ if (!props.getPublisherConsumerActive() && (consumer != null))
+ {
+ consumer.close();
+ }
+
+ return new CircuitEndBase(producer, consumer, session, messageMonitor, exceptionMonitor);
+ }
+
+ /**
+ * Builds a circuit end suitable for the receiving side of a test circuit, from standard test parameters.
+ *
+ * @param connection The connection to build the circuit end on.
+ * @param testProps The test parameters to configure the circuit end construction.
+ * @param uniqueId A unique number to being numbering destinations from, to make this circuit unique.
+ *
+ * @return A circuit end suitable for the receiving side of a test circuit.
+ *
+ * @throws JMSException Any underlying JMSExceptions are allowed to fall through and fail the creation.
+ */
+ public CircuitEndBase createReceiverCircuitEnd(Connection connection, ParsedProperties testProps, long uniqueId)
+ throws JMSException
+ {
+ log.debug(
+ "public CircuitEndBase createReceiverCircuitEnd(Connection connection, ParsedProperties testProps, long uniqueId = "
+ + uniqueId + "): called");
+
+ // Cast the test properties into a typed interface for convenience.
+ MessagingTestConfigProperties props = new MessagingTestConfigProperties(testProps);
+
+ // Check that the test properties do not contain AMQP/Qpid specific settings, and fail if they do.
+ if (props.getImmediate() || props.getMandatory())
+ {
+ throw new RuntimeException(
+ "Cannot create a pure JMS circuit as the test properties require AMQP specific options.");
+ }
+
+ Session session = connection.createSession(props.getPublisherTransacted(), props.getAckMode());
+
+ MessageProducer producer =
+ props.getReceiverProducerBind()
+ ? session.createProducer(session.createQueue(props.getReceiveDestinationNameRoot() + "_" + uniqueId)) : null;
+
+ Destination destination =
+ props.getPubsub() ? session.createTopic(props.getSendDestinationNameRoot() + "_" + uniqueId)
+ : session.createQueue(props.getSendDestinationNameRoot() + "_" + uniqueId);
+
+ MessageConsumer consumer =
+ props.getReceiverConsumerBind()
+ ? ((props.getDurableSubscription() && props.getPubsub())
+ ? session.createDurableSubscriber((Topic) destination, "testsub") : session.createConsumer(destination))
+ : null;
+
+ MessageMonitor messageMonitor = new MessageMonitor();
+
+ if (consumer != null)
+ {
+ consumer.setMessageListener(messageMonitor);
+ }
+
+ if (!props.getReceiverConsumerActive() && (consumer != null))
+ {
+ consumer.close();
+ }
+
+ return new CircuitEndBase(producer, consumer, session, messageMonitor, null);
+ }
+
+ /**
+ * Sets the sender test client to coordinate the test with.
+ *
+ * @param sender The contact details of the sending client in the test.
+ */
+ public void setSender(TestClientDetails sender)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /**
+ * Sets the receiving test client to coordinate the test with.
+ *
+ * @param receiver The contact details of the sending client in the test.
+ */
+ public void setReceiver(TestClientDetails receiver)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /**
+ * Supplies the sending test client.
+ *
+ * @return The sending test client.
+ */
+ public TestClientDetails getSender()
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /**
+ * Supplies the receiving test client.
+ *
+ * @return The receiving test client.
+ */
+ public List<TestClientDetails> getReceivers()
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+
+ /**
+ * Accepts the conversation factory over which to hold the test coordinating conversation.
+ *
+ * @param conversationFactory The conversation factory to coordinate the test over.
+ */
+ public void setConversationFactory(ConversationFactory conversationFactory)
+ {
+ throw new RuntimeException("Not implemented.");
+ }
+}