| /* | |
| * | |
| * 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. | |
| * | |
| */ | |
| using log4net; | |
| using Apache.Qpid.Integration.Tests.framework.localcircuit;//.LocalCircuitImpl; | |
| //using Apache.Qpid.Integration.Tests.framework.localcircuit.LocalPublisherImpl; | |
| //using Apache.Qpid.Integration.Tests.framework.localcircuit.LocalReceiverImpl; | |
| //using Apache.Qpid.Integration.Tests.framework.sequencers.CircuitFactory; | |
| //using org.apache.qpid.util.ConversationFactory; | |
| //using uk.co.thebadgerset.junit.extensions.util.ParsedProperties; | |
| //using javax.jms.*; | |
| using System.Collections.Generic;//.IList; | |
| //using java.util.Properties; | |
| //using java.util.concurrent.atomic.AtomicLong; | |
| namespace Apache.Qpid.Integration.Tests.framework | |
| { | |
| /// <summary> | |
| /// 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 <see cref="Publisher"/> and <see cref="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> | |
| /// </summary> | |
| public class LocalCircuitFactory : CircuitFactory | |
| { | |
| /// <summary> Used for debugging. </summary> | |
| private static ILog log = LogManager.GetLogger(typeof(LocalCircuitFactory)); | |
| /// <summary> Used to create unique destination names for each test. </summary> | |
| protected static AtomicLong uniqueDestsId = new AtomicLong(); | |
| /// <summary> | |
| /// 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. | |
| /// </summary> | |
| /// <param name="testCircuit"> The test circuit. </param> | |
| /// <param name="assertions"> The list of assertions to apply to the test circuit. </param> | |
| /// <param name="testProperties"> The test case definition. </param> | |
| public void sequenceTest(Circuit testCircuit, IList<Assertion> assertions, Properties testProperties) | |
| { | |
| FrameworkBaseCase.assertNoFailures(testCircuit.test(1, assertions)); | |
| } | |
| /// <summary> | |
| /// Creates a test circuit for the test, configered by the test parameters specified. | |
| /// </summary> | |
| /// <param name="testProperties"> The test parameters. </param> | |
| /// | |
| /// <return> A test circuit. </return> | |
| public Circuit createCircuit(TestModel testProperties) | |
| { | |
| Circuit result; | |
| // 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(); | |
| // Set up the connection. | |
| Connection connection = TestUtils.createConnection(testProperties); | |
| // 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, testProps, uniqueId); | |
| // Set up the receiver. | |
| CircuitEndBase receiverEnd = createReceiverCircuitEnd(connection, testProps, uniqueId); | |
| // Start listening for incoming messages. | |
| connection.start(); | |
| // Namespace 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; | |
| } | |
| /// <summary> | |
| /// Creates a local <see cref="Receiver"/> from a <see cref="CircuitEnd"/>. Sub-classes may override this to provide more | |
| /// specialized receivers if necessary. | |
| /// </summary> | |
| /// <param name="receiverEnd"> The receiving circuit end. </param> | |
| /// | |
| /// <return> A <see cref="Receiver"/>. </return> | |
| protected LocalReceiverImpl createReceiverFromCircuitEnd(CircuitEndBase receiverEnd) | |
| { | |
| return new LocalReceiverImpl(receiverEnd); | |
| } | |
| /// <summary> | |
| /// Creates a local <see cref="Publisher"/> from a <see cref="CircuitEnd"/>. Sub-classes may override this to provide more | |
| /// specialized receivers if necessary. | |
| /// </summary> | |
| /// <param name="publisherEnd"> The publishing circuit end. </param> | |
| /// | |
| /// <return> A <see cref="Receiver"/>. </return> | |
| protected LocalPublisherImpl createPublisherFromCircuitEnd(CircuitEndBase publisherEnd) | |
| { | |
| return new LocalPublisherImpl(publisherEnd); | |
| } | |
| /// <summary> | |
| /// Builds a circuit end suitable for the publishing side of a test circuit, from standard test parameters. | |
| /// </summary> | |
| /// <param name="connection"> The connection to build the circuit end on. </param> | |
| /// <param name="testProps"> The test parameters to configure the circuit end construction. </param> | |
| /// <param name="uniqueId"> A unique number to being numbering destinations from, to make this circuit unique. </param> | |
| /// | |
| /// <return> A circuit end suitable for the publishing side of a test circuit. </return> | |
| /// | |
| /// <exception cref="JMSException"> Any underlying JMSExceptions are allowed to fall through and fail the creation. </exception> | |
| public CircuitEndBase createPublisherCircuitEnd(Connection connection, TestModel testProps, long uniqueId) | |
| throws JMSException | |
| { | |
| log.debug( | |
| "public CircuitEndBase createPublisherCircuitEnd(Connection connection, TestModel testProps, long uniqueId = " | |
| + uniqueId + "): called"); | |
| // Check that the test properties do not contain AMQP/Qpid specific settings, and fail if they do. | |
| if (testProps.getImmediate() || testProps.getMandatory()) | |
| { | |
| throw new RuntimeException( | |
| "Cannot create a pure JMS circuit as the test properties require AMQP specific options."); | |
| } | |
| Session session = connection.createSession(testProps.getPublisherTransacted(), testProps.getAckMode()); | |
| Destination destination = | |
| testProps.getPubsub() ? session.createTopic(testProps.getSendDestinationNameRoot() + "_" + uniqueId) | |
| : session.createQueue(testProps.getSendDestinationNameRoot() + "_" + uniqueId); | |
| MessageProducer producer = testProps.getPublisherProducerBind() ? session.createProducer(destination) : null; | |
| MessageConsumer consumer = | |
| testProps.getPublisherConsumerBind() | |
| ? session.createConsumer(session.createQueue(testProps.getReceiveDestinationNameRoot() + "_" + uniqueId)) : null; | |
| MessageMonitor messageMonitor = new MessageMonitor(); | |
| if (consumer != null) | |
| { | |
| consumer.setMessageListener(messageMonitor); | |
| } | |
| ExceptionMonitor exceptionMonitor = new ExceptionMonitor(); | |
| connection.setExceptionListener(exceptionMonitor); | |
| if (!testProps.getPublisherConsumerActive() && (consumer != null)) | |
| { | |
| consumer.close(); | |
| } | |
| return new CircuitEndBase(producer, consumer, session, messageMonitor, exceptionMonitor); | |
| } | |
| /// <summary> | |
| /// Builds a circuit end suitable for the receiving side of a test circuit, from standard test parameters. | |
| /// </summary> | |
| /// <param name="connection"> The connection to build the circuit end on. </param> | |
| /// <param name="testProps"> The test parameters to configure the circuit end construction. </param> | |
| /// <param name="uniqueId"> A unique number to being numbering destinations from, to make this circuit unique. </param> | |
| /// | |
| /// <return> A circuit end suitable for the receiving side of a test circuit. </return> | |
| /// | |
| /// <exception cref="JMSException"> Any underlying JMSExceptions are allowed to fall through and fail the creation. </exception> | |
| public CircuitEndBase createReceiverCircuitEnd(Connection connection, TestModel testProps, long uniqueId) | |
| throws JMSException | |
| { | |
| log.debug( | |
| "public CircuitEndBase createReceiverCircuitEnd(Connection connection, TestModel testProps, long uniqueId = " | |
| + uniqueId + "): called"); | |
| // Check that the test properties do not contain AMQP/Qpid specific settings, and fail if they do. | |
| if (testProps.getImmediate() || testProps.getMandatory()) | |
| { | |
| throw new RuntimeException( | |
| "Cannot create a pure JMS circuit as the test properties require AMQP specific options."); | |
| } | |
| Session session = connection.createSession(testProps.getPublisherTransacted(), testProps.getAckMode()); | |
| MessageProducer producer = | |
| testProps.getReceiverProducerBind() | |
| ? session.createProducer(session.createQueue(testProps.getReceiveDestinationNameRoot() + "_" + uniqueId)) : null; | |
| Destination destination = | |
| testProps.getPubsub() ? session.createTopic(testProps.getSendDestinationNameRoot() + "_" + uniqueId) | |
| : session.createQueue(testProps.getSendDestinationNameRoot() + "_" + uniqueId); | |
| MessageConsumer consumer = | |
| testProps.getReceiverConsumerBind() | |
| ? ((testProps.getDurableSubscription() && testProps.getPubsub()) | |
| ? session.createDurableSubscriber((Topic) destination, "testsub") : session.createConsumer(destination)) | |
| : null; | |
| MessageMonitor messageMonitor = new MessageMonitor(); | |
| if (consumer != null) | |
| { | |
| consumer.setMessageListener(messageMonitor); | |
| } | |
| if (!testProps.getReceiverConsumerActive() && (consumer != null)) | |
| { | |
| consumer.close(); | |
| } | |
| return new CircuitEndBase(producer, consumer, session, messageMonitor, null); | |
| } | |
| /* | |
| /// <summary> | |
| /// Sets the sender test client to coordinate the test with. | |
| /// </summary> | |
| /// <param name="sender"> The contact details of the sending client in the test. </param> | |
| public void setSender(TestClientDetails sender) | |
| { | |
| throw new RuntimeException("Not implemented."); | |
| } | |
| /// <summary> | |
| /// Sets the receiving test client to coordinate the test with. | |
| /// </summary> | |
| /// <param name="receiver"> The contact details of the sending client in the test. </param> | |
| public void setReceiver(TestClientDetails receiver) | |
| { | |
| throw new RuntimeException("Not implemented."); | |
| } | |
| /// <summary> | |
| /// Supplies the sending test client. | |
| /// </summary> | |
| /// <return> The sending test client. </return> | |
| public TestClientDetails getSender() | |
| { | |
| throw new RuntimeException("Not implemented."); | |
| } | |
| /// <summary> | |
| /// Supplies the receiving test client. | |
| /// </summary> | |
| /// <return> The receiving test client. </return> | |
| public IList<TestClientDetails> getReceivers() | |
| { | |
| throw new RuntimeException("Not implemented."); | |
| } | |
| */ | |
| /* | |
| /// <summary> | |
| /// Accepts the conversation factory over which to hold the test coordinating conversation. | |
| /// </summary> | |
| /// <param name="conversationFactory"> The conversation factory to coordinate the test over. </param> | |
| public void setConversationFactory(ConversationFactory conversationFactory) | |
| { | |
| throw new RuntimeException("Not implemented."); | |
| } | |
| */ | |
| } | |
| } |