本文主要研究一下artemis对junit的支持
junit-4.12-sources.jar!/org/junit/rules/TestRule.java
public interface TestRule { /** * Modifies the method-running {@link Statement} to implement this * test-running rule. * * @param base The {@link Statement} to be modified * @param description A {@link Description} of the test implemented in {@code base} * @return a new statement, which may be the same as {@code base}, * a wrapper around {@code base}, or a completely new Statement. */ Statement apply(Statement base, Description description); }
junit-4.12-sources.jar!/org/junit/rules/ExternalResource.java
public abstract class ExternalResource implements TestRule { public Statement apply(Statement base, Description description) { return statement(base); } private Statement statement(final Statement base) { return new Statement() { @Override public void evaluate() throws Throwable { before(); try { base.evaluate(); } finally { after(); } } }; } /** * Override to set up your specific external resource. * * @throws Throwable if setup fails (which will disable {@code after} */ protected void before() throws Throwable { // do nothing } /** * Override to tear down your specific external resource. */ protected void after() { // do nothing } }
activemq-artemis-2.11.0/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/EmbeddedActiveMQResource.java
public class EmbeddedActiveMQResource extends ExternalResource { //...... /** * Invoked by JUnit to setup the resource - start the embedded ActiveMQ Artemis server */ @Override protected void before() throws Throwable { log.info("Starting {}: {}", this.getClass().getSimpleName(), getServerName()); this.start(); super.before(); } /** * Invoked by JUnit to tear down the resource - stops the embedded ActiveMQ Artemis server */ @Override protected void after() { log.info("Stopping {}: {}", this.getClass().getSimpleName(), getServerName()); this.stop(); super.after(); } public void start() { try { server.start(); } catch (Exception ex) { throw new RuntimeException(String.format("Exception encountered starting %s: %s", server.getClass().getName(), this.getServerName()), ex); } configuration = server.getActiveMQServer().getConfiguration(); } public void stop() { if (internalClient != null) { internalClient.stop(); internalClient = null; } if (server != null) { try { server.stop(); } catch (Exception ex) { log.warn(String.format("Exception encountered stopping %s: %s", server.getClass().getSimpleName(), this.getServerName()), ex); } } } //...... }
activemq-artemis-2.11.0/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/AbstractActiveMQClientResource.java
public abstract class AbstractActiveMQClientResource extends ExternalResource { //...... @Override protected void before() throws Throwable { super.before(); start(); } @Override protected void after() { stop(); super.after(); } void start() { log.info("Starting {}", this.getClass().getSimpleName()); try { sessionFactory = serverLocator.createSessionFactory(); session = sessionFactory.createSession(username, password, false, true, true, serverLocator.isPreAcknowledge(), serverLocator.getAckBatchSize()); } catch (RuntimeException runtimeEx) { throw runtimeEx; } catch (Exception ex) { throw new ActiveMQClientResourceException(String.format("%s initialisation failure", this.getClass().getSimpleName()), ex); } createClient(); try { session.start(); } catch (ActiveMQException amqEx) { throw new ActiveMQClientResourceException(String.format("%s startup failure", this.getClass().getSimpleName()), amqEx); } } void stop() { stopClient(); if (session != null) { try { session.close(); } catch (ActiveMQException amqEx) { log.warn("ActiveMQException encountered closing InternalClient ClientSession - ignoring", amqEx); } finally { session = null; } } if (sessionFactory != null) { sessionFactory.close(); sessionFactory = null; } if (serverLocator != null) { serverLocator.close(); serverLocator = null; } } protected abstract void createClient(); protected abstract void stopClient(); //...... }
activemq-artemis-2.11.0/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/ActiveMQProducerResource.java
public class ActiveMQProducerResource extends AbstractActiveMQClientResource { //...... @Override protected void createClient() { try { if (!session.addressQuery(address).isExists() && autoCreateQueue) { log.warn("{}: queue does not exist - creating queue: address = {}, name = {}", this.getClass().getSimpleName(), address.toString(), address.toString()); session.createQueue(address, address); } producer = session.createProducer(address); } catch (ActiveMQException amqEx) { throw new ActiveMQClientResourceException(String.format("Error creating producer for address %s", address.toString()), amqEx); } } @Override protected void stopClient() { if (producer != null) { try { producer.close(); } catch (ActiveMQException amqEx) { log.warn("ActiveMQException encountered closing InternalClient ClientProducer - ignoring", amqEx); } finally { producer = null; } } } //...... }
activemq-artemis-2.11.0/artemis-junit/src/main/java/org/apache/activemq/artemis/junit/ActiveMQConsumerResource.java
public class ActiveMQConsumerResource extends AbstractActiveMQClientResource { //...... @Override protected void createClient() { boolean browseOnly = false; try { if (!session.queueQuery(queueName).isExists() && autoCreateQueue) { log.warn("{}: queue does not exist - creating queue: address = {}, name = {}", this.getClass().getSimpleName(), queueName.toString(), queueName.toString()); session.createAddress(queueName, RoutingType.MULTICAST, true); session.createQueue(queueName, queueName); } consumer = session.createConsumer(queueName, browseOnly); } catch (ActiveMQException amqEx) { throw new ActiveMQClientResourceException(String.format("Error creating consumer for queueName %s", queueName.toString()), amqEx); } } @Override protected void stopClient() { if (consumer != null) { try { consumer.close(); } catch (ActiveMQException amqEx) { log.warn("Exception encountered closing consumer - ignoring", amqEx); } finally { consumer = null; } } } //...... }
artemis对junit的ExternalResource提供了扩展,对于server端提供了EmbeddedActiveMQResource,对于client端提供了AbstractActiveMQClientResource( ActiveMQProducerResource、ActiveMQConsumerResource
)