├── embedded-jms-junit ├── src │ ├── main │ │ └── java │ │ │ └── org │ │ │ └── zapodot │ │ │ └── junit │ │ │ └── jms │ │ │ ├── package-info.java │ │ │ ├── impl │ │ │ ├── package-info.java │ │ │ └── EmbeddedJmsRuleImpl.java │ │ │ ├── EmbeddedJmsRuleBuilder.java │ │ │ └── EmbeddedJmsRule.java │ └── test │ │ └── java │ │ └── org │ │ └── zapodot │ │ └── junit │ │ └── jms │ │ ├── EmbeddedJmsRuleMarshalEnabledTest.java │ │ ├── impl │ │ └── EmbeddedJmsRuleImplTest.java │ │ ├── SendReceivable.java │ │ ├── EmbeddedJmsRuleSpringJmsTest.java │ │ ├── EmbeddedJmsRuleCamelTest.java │ │ ├── CallablesForSendingAndReceiving.java │ │ └── EmbeddedJmsRuleStandardSetupTest.java └── pom.xml ├── embedded-jms-junit5 ├── src │ ├── main │ │ └── java │ │ │ └── org │ │ │ └── zapodot │ │ │ └── junit5 │ │ │ └── jms │ │ │ ├── package-info.java │ │ │ ├── internal │ │ │ ├── package-info.java │ │ │ ├── InjectableFieldsAccessor.java │ │ │ ├── BrokerConfiguration.java │ │ │ ├── BrokerConfigurationBuilder.java │ │ │ └── FieldInjector.java │ │ │ ├── annotations │ │ │ ├── package-info.java │ │ │ ├── EmbeddedJms.java │ │ │ └── BrokerConfig.java │ │ │ └── EmbeddedJmsBroker.java │ └── test │ │ └── java │ │ └── org │ │ └── zapodot │ │ └── junit5 │ │ └── jms │ │ ├── AbstractJmsTest.java │ │ ├── EmbeddedJmsBrokerSubclassTest.java │ │ ├── EmbeddedJmsBrokerRegisterExtensionStaticFieldTest.java │ │ ├── EmbeddedJmsDefaultSetupTest.java │ │ ├── internal │ │ ├── FieldInjectorTest.java │ │ └── BrokerConfigurationTest.java │ │ ├── EmbeddedJmsBrokerWithConfigTest.java │ │ ├── EmbeddedJmsBrokerRegisterExtensionFieldTest.java │ │ ├── EmbeddedJmsBrokerNestedTest.java │ │ ├── EmbeddedJmsBrokerWithParameterTest.java │ │ ├── EmbeddedJmsBrokerPersistenceTest.java │ │ ├── EmbeddedJmsBrokerRequestReplySpringTest.java │ │ └── EmbeddedJmsBrokerCamelTest.java └── pom.xml ├── embedded-jms-core ├── src │ ├── main │ │ └── java │ │ │ └── org │ │ │ └── zapodot │ │ │ └── jms │ │ │ └── common │ │ │ ├── BrokerURIAccessor.java │ │ │ ├── package-info.java │ │ │ ├── ConnectionFactoryAccessor.java │ │ │ ├── ActiveMQConnectionFactoryAccessor.java │ │ │ ├── BrokerSettings.java │ │ │ └── EmbeddedJMSBrokerHolder.java │ └── test │ │ └── java │ │ └── org │ │ └── zapodot │ │ └── jms │ │ └── common │ │ ├── TemporaryDirectory.java │ │ ├── EmbeddedJMSBrokerHolderTest.java │ │ └── EmbeddedJMSBrokerHolderConfigurerTest.java └── pom.xml ├── .gitignore ├── .github ├── dependabot.yml └── workflows │ └── maven.yml ├── old.travis.yml ├── CODE_OF_CONDUCT.md ├── README.md ├── LICENSE └── pom.xml /embedded-jms-junit/src/main/java/org/zapodot/junit/jms/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Public API 3 | * 4 | * @author zapodot at gmail dot com 5 | */ 6 | package org.zapodot.junit.jms; -------------------------------------------------------------------------------- /embedded-jms-junit5/src/main/java/org/zapodot/junit5/jms/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Public API 3 | * 4 | * @author zapodot at gmail dot com 5 | */ 6 | package org.zapodot.junit5.jms; -------------------------------------------------------------------------------- /embedded-jms-core/src/main/java/org/zapodot/jms/common/BrokerURIAccessor.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.jms.common; 2 | 3 | import java.net.URI; 4 | 5 | public interface BrokerURIAccessor { 6 | URI getBrokerUri(); 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # maven files # 2 | target/ 3 | pom.xml.tag 4 | pom.xml.releaseBackup 5 | pom.xml.versionsBackup 6 | pom.xml.next 7 | release.properties 8 | 9 | # idea Files # 10 | .idea 11 | *.ipr 12 | *.iml 13 | *.iws 14 | -------------------------------------------------------------------------------- /embedded-jms-core/src/main/java/org/zapodot/jms/common/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Internal API. May be removed, moved or changed without prior deprecation 3 | * 4 | * @author zapodot at gmail dot com 5 | */ 6 | package org.zapodot.jms.common; -------------------------------------------------------------------------------- /embedded-jms-junit/src/main/java/org/zapodot/junit/jms/impl/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Internal API. May be removed, moved or changed without prior deprecation 3 | * 4 | * @author zapodot at gmail dot com 5 | */ 6 | package org.zapodot.junit.jms.impl; -------------------------------------------------------------------------------- /embedded-jms-junit5/src/main/java/org/zapodot/junit5/jms/internal/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Internal API. May be removed, moved or changed without prior deprecation 3 | * 4 | * @author zapodot at gmail dot com 5 | */ 6 | package org.zapodot.junit5.jms.internal; -------------------------------------------------------------------------------- /embedded-jms-core/src/main/java/org/zapodot/jms/common/ConnectionFactoryAccessor.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.jms.common; 2 | 3 | import javax.jms.ConnectionFactory; 4 | 5 | public interface ConnectionFactoryAccessor { 6 | ConnectionFactory getConnectionFactory(); 7 | } 8 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/main/java/org/zapodot/junit5/jms/annotations/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Public API - annotations used to support declarative style configuration and injection 3 | * 4 | * @author zapodot at gmail dot com 5 | */ 6 | package org.zapodot.junit5.jms.annotations; -------------------------------------------------------------------------------- /embedded-jms-core/src/main/java/org/zapodot/jms/common/ActiveMQConnectionFactoryAccessor.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.jms.common; 2 | 3 | import org.apache.activemq.ActiveMQConnectionFactory; 4 | 5 | public interface ActiveMQConnectionFactoryAccessor { 6 | ActiveMQConnectionFactory getActiveMQConnectionFactory(); 7 | } 8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "maven" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "daily" 12 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/main/java/org/zapodot/junit5/jms/annotations/EmbeddedJms.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Inherited; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * Inject a JMS ConnectionFactory to the given field or parameter. 12 | */ 13 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Inherited 16 | @Documented 17 | public @interface EmbeddedJms { 18 | } 19 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/test/java/org/zapodot/junit5/jms/AbstractJmsTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms; 2 | 3 | import org.junit.jupiter.api.extension.ExtendWith; 4 | import org.zapodot.junit5.jms.annotations.BrokerConfig; 5 | import org.zapodot.junit5.jms.annotations.EmbeddedJms; 6 | 7 | import javax.jms.ConnectionFactory; 8 | 9 | @ExtendWith(EmbeddedJmsBroker.class) 10 | @BrokerConfig(name = AbstractJmsTest.BROKER_SUPER_BROKER) 11 | public abstract class AbstractJmsTest { 12 | 13 | protected static final String BROKER_SUPER_BROKER = "SuperDuperBroker"; 14 | 15 | @EmbeddedJms 16 | protected ConnectionFactory connectionFactory; 17 | } 18 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/test/java/org/zapodot/junit5/jms/EmbeddedJmsBrokerSubclassTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.zapodot.junit5.jms.annotations.EmbeddedJms; 5 | 6 | import javax.jms.ConnectionFactory; 7 | import java.net.URI; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | import static org.junit.jupiter.api.Assertions.assertNotNull; 11 | 12 | public class EmbeddedJmsBrokerSubclassTest extends AbstractJmsTest { 13 | 14 | @EmbeddedJms 15 | private ConnectionFactory subConnectionFactory; 16 | 17 | @EmbeddedJms 18 | private URI brokerUri; 19 | 20 | @Test 21 | void testIfInjectionWorksIfDefinedInSuperClass() { 22 | assertNotNull(super.connectionFactory); 23 | assertNotNull(subConnectionFactory); 24 | assertEquals("vm://" + AbstractJmsTest.BROKER_SUPER_BROKER, brokerUri.toString()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/test/java/org/zapodot/junit5/jms/EmbeddedJmsBrokerRegisterExtensionStaticFieldTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms; 2 | 3 | import org.junit.jupiter.api.DisplayName; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.extension.RegisterExtension; 6 | import org.zapodot.junit5.jms.annotations.EmbeddedJms; 7 | 8 | import javax.jms.ConnectionFactory; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertNotNull; 11 | 12 | @DisplayName("Injection using @RegisterExtension on static field") 13 | class EmbeddedJmsBrokerRegisterExtensionStaticFieldTest { 14 | 15 | @RegisterExtension 16 | static EmbeddedJmsBroker embeddedJMSBroker = new EmbeddedJmsBroker(); 17 | 18 | @EmbeddedJms 19 | private ConnectionFactory connectionFactory; 20 | 21 | @DisplayName("injection on fields works") 22 | @Test 23 | void checkInjectionViaRegisterExtension() { 24 | assertNotNull(connectionFactory); 25 | } 26 | } -------------------------------------------------------------------------------- /embedded-jms-junit/src/test/java/org/zapodot/junit/jms/EmbeddedJmsRuleMarshalEnabledTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit.jms; 2 | 3 | import org.junit.Rule; 4 | import org.junit.Test; 5 | 6 | import javax.jms.ConnectionFactory; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class EmbeddedJmsRuleMarshalEnabledTest implements SendReceivable { 11 | private static final String TEST_QUEUE = EmbeddedJmsRuleMarshalEnabledTest.class.getSimpleName(); 12 | private static final String TEST_MESSAGE = "Test with wire format marshal"; 13 | @Rule 14 | public EmbeddedJmsRule embeddedJmsRule = EmbeddedJmsRule.builder().withMarshalEnabled().withName("named").build(); 15 | 16 | @Test 17 | public void sendAndReceiveUsingWireFormat() throws Exception { 18 | final ConnectionFactory connectionFactory = embeddedJmsRule.connectionFactory(); 19 | assertEquals(TEST_MESSAGE, sendReceive(connectionFactory, TEST_QUEUE, TEST_MESSAGE)); 20 | } 21 | } -------------------------------------------------------------------------------- /embedded-jms-junit/src/test/java/org/zapodot/junit/jms/impl/EmbeddedJmsRuleImplTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit.jms.impl; 2 | 3 | import org.junit.Test; 4 | 5 | /** 6 | * @author sondre 7 | */ 8 | public class EmbeddedJmsRuleImplTest { 9 | 10 | @Test(expected = IllegalStateException.class) 11 | public void connectionFactory() throws Exception { 12 | final EmbeddedJmsRuleImpl rule = new EmbeddedJmsRuleImpl("predefined", true, false); 13 | rule.connectionFactory(); 14 | } 15 | 16 | @Test(expected = IllegalStateException.class) 17 | public void activeMqConnectionFactory() throws Exception { 18 | final EmbeddedJmsRuleImpl rule = new EmbeddedJmsRuleImpl("predefined", true, false); 19 | rule.activeMqConnectionFactory(); 20 | } 21 | 22 | @Test(expected = IllegalStateException.class) 23 | public void brokerUri() throws Exception { 24 | final EmbeddedJmsRuleImpl rule = new EmbeddedJmsRuleImpl("predefined", true, false); 25 | rule.brokerUri(); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /embedded-jms-core/src/main/java/org/zapodot/jms/common/BrokerSettings.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.jms.common; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * Internal broker configuration holder. 7 | *

8 | * This is part of the internal API and may be changed or removed without prior notice. 9 | */ 10 | class BrokerSettings { 11 | private final String name; 12 | 13 | private final boolean marshal; 14 | 15 | private final boolean persistent; 16 | 17 | private final File tempDir; 18 | 19 | BrokerSettings(final String name, final boolean marshal, final boolean persistent, final File tempDir) { 20 | this.name = name; 21 | this.marshal = marshal; 22 | this.persistent = persistent; 23 | this.tempDir = tempDir; 24 | } 25 | 26 | String getName() { 27 | return name; 28 | } 29 | 30 | boolean isMarshal() { 31 | return marshal; 32 | } 33 | 34 | boolean isPersistent() { 35 | return persistent; 36 | } 37 | 38 | File getTempDir() { 39 | return tempDir; 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/test/java/org/zapodot/junit5/jms/EmbeddedJmsDefaultSetupTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms; 2 | 3 | import org.apache.activemq.ActiveMQConnectionFactory; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.extension.ExtendWith; 6 | import org.zapodot.junit5.jms.annotations.EmbeddedJms; 7 | 8 | import javax.jms.ConnectionFactory; 9 | import java.net.URI; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertEquals; 12 | import static org.junit.jupiter.api.Assertions.assertNotNull; 13 | 14 | @ExtendWith(EmbeddedJmsBroker.class) 15 | class EmbeddedJmsDefaultSetupTest { 16 | 17 | @EmbeddedJms 18 | private ConnectionFactory connectionFactory; 19 | 20 | @EmbeddedJms 21 | private ActiveMQConnectionFactory activeMQConnectionFactory; 22 | 23 | @EmbeddedJms 24 | private URI brokerUri; 25 | 26 | 27 | @Test 28 | void fieldsAreInjected() { 29 | assertNotNull(connectionFactory); 30 | assertNotNull(activeMQConnectionFactory); 31 | assertNotNull(brokerUri); 32 | } 33 | 34 | @Test 35 | void brokerUriGenerated() { 36 | assertEquals("vm://" + getClass().getSimpleName(), brokerUri.toString()); 37 | } 38 | } -------------------------------------------------------------------------------- /embedded-jms-junit5/src/main/java/org/zapodot/junit5/jms/annotations/BrokerConfig.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Inherited; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | /** 11 | * Configuration for the Embedded JMS Broker 12 | */ 13 | @Target({ElementType.TYPE, ElementType.METHOD}) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Inherited 16 | @Documented 17 | public @interface BrokerConfig { 18 | /** 19 | * The name of the broker. If not specified it will default to the name of the test method 20 | * 21 | * @return the provided 22 | */ 23 | String name() default ""; 24 | 25 | /** 26 | * Whether marshalling of messages should be enabled or not (default: false) 27 | * 28 | * @return a boolean string 29 | */ 30 | String marshall() default ""; 31 | 32 | /** 33 | * Whether message persistence should be enabled or not. Default is false 34 | * 35 | * @return a boolean string 36 | */ 37 | String persistence() default ""; 38 | } 39 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Build, test and deploy 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | matrix: 10 | java: [8, 11] 11 | name: Java ${{ matrix.java }} 12 | env: 13 | CC_TEST_REPORTER_ID: 47b239597faea3da257baa211d7438ff8ba9047319a2c687110f4f8e41bb07f1 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Set up Java ${{ matrix.java }} 17 | uses: actions/setup-java@v1 18 | with: 19 | java-version: ${{ matrix.java }} 20 | - name: Build with Maven 21 | run: mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V 22 | id: mvnInstall 23 | - name: Run tests 24 | run: mvn test -B 25 | id: mvnTest 26 | - name: Record coverage 27 | run: | 28 | mvn clean cobertura:cobertura coveralls:report 29 | # if: startsWith(matrix.java, 8) 30 | # - name: Deploy to Github packages 31 | # env: 32 | # token: ${{ secrets.GITHUB_TOKEN }} 33 | # packagesUrl: https://maven.pkg.github.com/zapodot 34 | # run: | 35 | # mvn deploy -Dregistry=$packagesUrl -Dtoken=$token 36 | # id: deployGithubPackages 37 | # if: startsWith(matrix.java, 11) 38 | 39 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/test/java/org/zapodot/junit5/jms/internal/FieldInjectorTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms.internal; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.lang.reflect.Constructor; 6 | import java.lang.reflect.InvocationTargetException; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertFalse; 9 | import static org.junit.jupiter.api.Assertions.assertNotNull; 10 | import static org.junit.jupiter.api.Assertions.assertThrows; 11 | 12 | class FieldInjectorTest { 13 | 14 | @Test 15 | void instantiationNotAllowed() throws NoSuchMethodException { 16 | final Constructor constructor = FieldInjector.class.getDeclaredConstructor(); 17 | assertNotNull(constructor); 18 | assertFalse(constructor.isAccessible()); 19 | assertThrows(IllegalAccessException.class, constructor::newInstance); 20 | } 21 | 22 | @Test 23 | void instantiateAnyway() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { 24 | final Constructor constructor = FieldInjector.class.getDeclaredConstructor(); 25 | assertNotNull(constructor); 26 | try { 27 | constructor.setAccessible(true); 28 | assertNotNull(constructor.newInstance()); 29 | } finally { 30 | constructor.setAccessible(false); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /embedded-jms-junit5/src/test/java/org/zapodot/junit5/jms/EmbeddedJmsBrokerWithConfigTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms; 2 | 3 | import org.junit.jupiter.api.DisplayName; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.extension.ExtendWith; 6 | import org.zapodot.junit5.jms.annotations.BrokerConfig; 7 | import org.zapodot.junit5.jms.annotations.EmbeddedJms; 8 | 9 | import java.net.URI; 10 | 11 | import static org.junit.jupiter.api.Assertions.assertEquals; 12 | import static org.junit.jupiter.api.Assertions.assertNotNull; 13 | 14 | @DisplayName("Extension with custom configuration") 15 | @ExtendWith(EmbeddedJmsBroker.class) 16 | @BrokerConfig(name = EmbeddedJmsBrokerWithConfigTest.STUFF_BROKER) 17 | class EmbeddedJmsBrokerWithConfigTest { 18 | 19 | static final String STUFF_BROKER = "StuffBroker"; 20 | 21 | private static final String PRETTY_BROKER = "PrettyBroker"; 22 | 23 | @EmbeddedJms 24 | private URI uri; 25 | 26 | @DisplayName("class level") 27 | @Test 28 | void configuredUsingBrokerConfig() { 29 | assertNotNull(uri); 30 | assertEquals("vm://" + STUFF_BROKER, uri.toString()); 31 | } 32 | 33 | @DisplayName("method level configuration which overrides class level") 34 | @BrokerConfig(name = PRETTY_BROKER) 35 | @Test 36 | void brokerConfigOverriddenOnMethod() { 37 | assertEquals("vm://" + PRETTY_BROKER, uri.toString()); 38 | } 39 | } -------------------------------------------------------------------------------- /embedded-jms-junit/src/main/java/org/zapodot/junit/jms/EmbeddedJmsRuleBuilder.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit.jms; 2 | 3 | import org.zapodot.junit.jms.impl.EmbeddedJmsRuleImpl; 4 | 5 | /** 6 | * Builder that allows the setup of the Embedded JMS broker to be tweaked to individual needs 7 | */ 8 | public class EmbeddedJmsRuleBuilder { 9 | private String predefinedName; 10 | private boolean marshal = false; 11 | private boolean persistent = false; 12 | 13 | /** 14 | * Explicitly sets the name of the broker. Convenient if more then one broker is configured per test 15 | * 16 | * @param name the name to use for the broker 17 | * @return the same {@link EmbeddedJmsRuleBuilder} with the name property set 18 | */ 19 | public EmbeddedJmsRuleBuilder withName(final String name) { 20 | this.predefinedName = name; 21 | return this; 22 | } 23 | 24 | /** 25 | * Enables marshaling, meaning that all commands are sent and received using a {@link org.apache.activemq.wireformat.WireFormat} 26 | * 27 | * @return the same {@link EmbeddedJmsRuleBuilder} with the marshal property set to true 28 | */ 29 | public EmbeddedJmsRuleBuilder withMarshalEnabled() { 30 | this.marshal = true; 31 | return this; 32 | } 33 | 34 | public EmbeddedJmsRuleImpl build() { 35 | return new EmbeddedJmsRuleImpl(predefinedName, marshal, persistent); 36 | } 37 | } -------------------------------------------------------------------------------- /embedded-jms-junit/src/test/java/org/zapodot/junit/jms/SendReceivable.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit.jms; 2 | 3 | import javax.jms.ConnectionFactory; 4 | import javax.jms.JMSException; 5 | import java.util.concurrent.*; 6 | 7 | import static org.zapodot.junit.jms.CallablesForSendingAndReceiving.messagesFromTestQueue; 8 | import static org.zapodot.junit.jms.CallablesForSendingAndReceiving.sendMessageToQueue; 9 | 10 | public interface SendReceivable { 11 | default String sendReceive(final ConnectionFactory connectionFactory, 12 | final String queueName, 13 | final String textMessage) throws JMSException { 14 | final ExecutorService executorService = Executors.newFixedThreadPool(2); 15 | try { 16 | final Future messageFuture = executorService.submit(messagesFromTestQueue(connectionFactory, 17 | queueName)); 18 | executorService.submit(sendMessageToQueue(connectionFactory, queueName, textMessage)); 19 | return messageFuture.get(30L, TimeUnit.SECONDS); 20 | } catch (InterruptedException | ExecutionException | TimeoutException e) { 21 | throw new IllegalStateException("An error occurred during send/receive from JMS", e); 22 | } finally { 23 | executorService.shutdownNow(); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/main/java/org/zapodot/junit5/jms/internal/InjectableFieldsAccessor.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms.internal; 2 | 3 | import org.apache.activemq.ActiveMQConnectionFactory; 4 | import org.junit.platform.commons.util.AnnotationUtils; 5 | import org.zapodot.junit5.jms.annotations.EmbeddedJms; 6 | 7 | import javax.jms.ConnectionFactory; 8 | import java.lang.reflect.Field; 9 | import java.net.URI; 10 | import java.util.List; 11 | 12 | /** 13 | * InjectableFieldsAccessor - part of the internal API. May be removed, moved or changed without prior deprecation 14 | */ 15 | class InjectableFieldsAccessor { 16 | 17 | private InjectableFieldsAccessor() { 18 | } 19 | 20 | 21 | static List findInjectableFields(final Class type) { 22 | return AnnotationUtils.findAnnotatedFields(type, 23 | EmbeddedJms.class, 24 | field -> ConnectionFactory.class 25 | .isAssignableFrom(field.getType()) || 26 | ActiveMQConnectionFactory.class 27 | .isAssignableFrom(field.getType()) || 28 | URI.class 29 | .isAssignableFrom(field.getType())); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/test/java/org/zapodot/junit5/jms/internal/BrokerConfigurationTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms.internal; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | import static org.junit.jupiter.api.Assertions.assertNotEquals; 7 | 8 | class BrokerConfigurationTest { 9 | 10 | @Test 11 | void equalsNull() { 12 | assertNotEquals(BrokerConfigurationBuilder.instance().build(), null); 13 | } 14 | 15 | @Test 16 | void equalsOtherType() { 17 | assertNotEquals(BrokerConfigurationBuilder.instance().build(), ""); 18 | } 19 | 20 | @Test 21 | void equalsSame() { 22 | final BrokerConfiguration brokerConfiguration = BrokerConfigurationBuilder.instance().build(); 23 | assertEquals(brokerConfiguration, brokerConfiguration); 24 | } 25 | 26 | @Test 27 | void equalsSimilarInstances() { 28 | assertEquals(BrokerConfigurationBuilder.instance().build(), 29 | BrokerConfigurationBuilder.instance().build()); 30 | } 31 | 32 | @Test 33 | void testHashCode() { 34 | assertEquals(BrokerConfigurationBuilder.instance().build().hashCode(), 35 | BrokerConfigurationBuilder.instance().build().hashCode()); 36 | } 37 | 38 | @Test 39 | void testToString() { 40 | assertEquals(BrokerConfigurationBuilder.instance().build().toString(), 41 | BrokerConfigurationBuilder.instance().build().toString()); 42 | } 43 | } -------------------------------------------------------------------------------- /embedded-jms-junit5/src/test/java/org/zapodot/junit5/jms/EmbeddedJmsBrokerRegisterExtensionFieldTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms; 2 | 3 | import org.junit.jupiter.api.DisplayName; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.extension.RegisterExtension; 6 | import org.zapodot.junit5.jms.annotations.BrokerConfig; 7 | import org.zapodot.junit5.jms.annotations.EmbeddedJms; 8 | 9 | import javax.jms.ConnectionFactory; 10 | import java.net.URI; 11 | 12 | import static org.junit.jupiter.api.Assertions.assertNotEquals; 13 | import static org.junit.jupiter.api.Assertions.assertNotNull; 14 | 15 | @DisplayName("Injection using @RegisterExtension on field") 16 | @BrokerConfig(name = EmbeddedJmsBrokerRegisterExtensionFieldTest.BROKER_NAME) 17 | class EmbeddedJmsBrokerRegisterExtensionFieldTest { 18 | 19 | static final String BROKER_NAME = "StaticRegisterExtensionBroker"; 20 | 21 | @RegisterExtension 22 | final EmbeddedJmsBroker embeddedJMSBroker = new EmbeddedJmsBroker(); 23 | 24 | @EmbeddedJms 25 | private ConnectionFactory connectionFactory; 26 | 27 | @EmbeddedJms 28 | private URI brokerUri; 29 | 30 | @DisplayName("injection on fields works") 31 | @Test 32 | void checkInjectionViaRegisterExtension() { 33 | assertNotNull(connectionFactory); 34 | } 35 | 36 | @DisplayName("class level configuration not used") 37 | @Test 38 | void classLevelConfigurationNotUsed() { 39 | assertNotNull(brokerUri); 40 | assertNotEquals("vm://" + BROKER_NAME, brokerUri.toString()); 41 | } 42 | } -------------------------------------------------------------------------------- /embedded-jms-junit5/src/test/java/org/zapodot/junit5/jms/EmbeddedJmsBrokerNestedTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms; 2 | 3 | import org.apache.activemq.ActiveMQConnectionFactory; 4 | import org.junit.jupiter.api.DisplayName; 5 | import org.junit.jupiter.api.Nested; 6 | import org.junit.jupiter.api.Test; 7 | import org.junit.jupiter.api.extension.ExtendWith; 8 | import org.zapodot.junit5.jms.annotations.EmbeddedJms; 9 | 10 | import javax.jms.ConnectionFactory; 11 | 12 | import static org.junit.jupiter.api.Assertions.assertNotNull; 13 | 14 | @DisplayName("An embedded JMS ActiveMQ broker") 15 | @ExtendWith(EmbeddedJmsBroker.class) 16 | class EmbeddedJmsBrokerNestedTest { 17 | 18 | @EmbeddedJms 19 | private ConnectionFactory connectionFactory; 20 | 21 | @DisplayName("when javax.jms.ConnectionFactory is injected") 22 | @Test 23 | void injectionWorks() { 24 | assertNotNull(connectionFactory); 25 | } 26 | 27 | @Nested 28 | @DisplayName("in a nested test class") 29 | class WhenNested { 30 | 31 | @EmbeddedJms 32 | private ActiveMQConnectionFactory activeMQConnectionFactory; 33 | 34 | @DisplayName("the injection fields from the outer class is available") 35 | @Test 36 | void injectionWorksForNestedClasses() { 37 | assertNotNull(connectionFactory); 38 | } 39 | 40 | @DisplayName("injection works also for the internal class") 41 | @Test 42 | void injectionIntoFieldInNestedClass() { 43 | assertNotNull(activeMQConnectionFactory); 44 | 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /embedded-jms-junit/src/main/java/org/zapodot/junit/jms/EmbeddedJmsRule.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit.jms; 2 | 3 | import org.apache.activemq.ActiveMQConnectionFactory; 4 | import org.junit.rules.TestRule; 5 | 6 | import javax.jms.ConnectionFactory; 7 | import java.net.URI; 8 | 9 | /** 10 | * The general contract for the EmbeddedJmsRule. 11 | * 12 | * Example of use: 13 | * 14 | * public class MyTests { 15 | * 16 | * @Rule 17 | * public EmbeddedJmsRule embeddedJmsRule = EmbeddedJmsRule.builder().build(); 18 | * 19 | * @Test 20 | * public void testJmsIntegration() { 21 | * final ConnectionFactory connectionFactory = embeddedJmsRule.connectionFactory(); 22 | * // Do stuff 23 | * // ... 24 | * } 25 | * 26 | * } 27 | * 28 | */ 29 | public interface EmbeddedJmsRule extends TestRule { 30 | 31 | static EmbeddedJmsRuleBuilder builder() { 32 | return new EmbeddedJmsRuleBuilder(); 33 | } 34 | 35 | /** 36 | * Creates a ConnectionFactory that connects to the embedded broker 37 | * 38 | * @return a fresh instance of {@link ConnectionFactory} 39 | */ 40 | ConnectionFactory connectionFactory(); 41 | 42 | /** 43 | * Creates a {@link ActiveMQConnectionFactory} for those who needs access to the AMQ specific interface 44 | * 45 | * @return a fresh instance of {@link ActiveMQConnectionFactory} 46 | */ 47 | ActiveMQConnectionFactory activeMqConnectionFactory(); 48 | 49 | /** 50 | * An URI that may be used to connect to the embedded broker 51 | * 52 | * @return a {@link URI} 53 | */ 54 | URI brokerUri(); 55 | } 56 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/test/java/org/zapodot/junit5/jms/EmbeddedJmsBrokerWithParameterTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms; 2 | 3 | import org.apache.activemq.ActiveMQConnectionFactory; 4 | import org.junit.jupiter.api.DisplayName; 5 | import org.junit.jupiter.api.Test; 6 | import org.junit.jupiter.api.extension.ExtendWith; 7 | import org.zapodot.junit5.jms.annotations.EmbeddedJms; 8 | 9 | import javax.jms.ConnectionFactory; 10 | import java.net.URI; 11 | import java.sql.Connection; 12 | 13 | import static org.junit.jupiter.api.Assertions.assertNotNull; 14 | import static org.junit.jupiter.api.Assertions.assertNull; 15 | 16 | @ExtendWith(EmbeddedJmsBroker.class) 17 | @DisplayName("Inject parameter to test") 18 | class EmbeddedJmsBrokerWithParameterTest { 19 | 20 | @DisplayName("supports parameter type javax.jms.ConnectionFactory") 21 | @Test 22 | void connectionFactoryParameter(@EmbeddedJms ConnectionFactory connectionFactory) { 23 | assertNotNull(connectionFactory); 24 | } 25 | 26 | @DisplayName("supports parameter type org.apache.activemq.ActiveMQConnectionFactory") 27 | @Test 28 | void activeMQConnectionFactoryParameter(@EmbeddedJms ActiveMQConnectionFactory activeMQConnectionFactory) { 29 | assertNotNull(activeMQConnectionFactory); 30 | } 31 | 32 | @DisplayName("supports parameter type java.net.URI") 33 | @Test 34 | void brokerUriParameter(@EmbeddedJms URI brokerURI) { 35 | assertNotNull(brokerURI); 36 | } 37 | 38 | @DisplayName("not supported parameter type java.sql.Connection") 39 | @Test 40 | void otherType(@EmbeddedJms Connection connection) { 41 | // If the parameter is not supported it will neither be injected nor fail 42 | assertNull(connection); 43 | } 44 | } -------------------------------------------------------------------------------- /old.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: java 3 | env: 4 | global: 5 | - secure: 3YqqNwvMtdT4vOKa224ofn596Dcvks35cUrjInYaBN/y8Oq7TmNQn1thTwuZ3ZrS774xsOJ2inAbZ3aa9OJZEeV31oWjaupShNMk+K8gZ+Aq0LGcGgdcB1iwAOdsslDjzZlhEfPwdCUt3w01D2YRbqjhQiJThP5dZHMf7NfGyD49h04PYlbuDpmzj3DampQUCMmCZ1H2pro7O7khySHkxmZIgy2hUAVzoAAgpQqimE5jo+kMqZJtAbz7eAlKWYUy5kwFjyA6Nt46PuMUAAOYRLmZnskyuimsJUSbA0hbTLd9nYqM2cNhtq9fzslD2mnotTmeXbcXUyTEIgWofXSzDf9N1DOkGNz8G/GFvudv5+b0oyUtFW1+QOldjY8zoI0w6YJT+r6NcfXItK8/ENl0zCLlushldK0+GATE4ipZh6BiAUgP7jRcilg3DAklY3BZ4zVIJcxO7szslNkAyykCOAzna8GsFsOYYWoaBXqEXY2QQnTBZxmpYpiU4aYYSxTTnf6ursSU/YpQYSjS93b3WnKqpoZWmJbXIdARCjHt+KXWrU4oBL1HV6OSdnFmPhR3zD6w6xTeeYaCX8dnthwIDouoN18QTDZy860fPC0BnfxEZSrq2avN0ib1vmeljeHgawvFF3NBhNbtMRB78Y1Fyy4Wn97Ia0H2VHAi2Uem3GE= 6 | - secure: Zm5ZJNOfg+SSSF+9ZcX70Mm0soWfsV4kJbHGDyIqxnSn2SKSpaT91lR7yT15fccC2wihtWUCU8mpLeon/tJ9L4etnVc/VjF9bXd73msk987io5h7q08XbEp+H+JL5GFdMp/9iPvFYyi+tshUZBLjaeSd6MKwJ90jtcrS75t4iqI0FEhMtwHCUALLpkjubYWZJfGhIB2DviRwyHDqXWZlgQYJKzdJDZ5XKpbz06qz+dO0mnQelou3988bDY64yNahHoS5ZRiQu4748DKCWzsaJwD5HsWE1taGVjFC933AuKWW8F2obnNXTlLixzDaIidZ+GyBkC8dRIBAVZy6e1vgm0A4H6k7Z6qg4GYvfTObLK/xi3CfepSGdnXBHRGRVePpC6bMqngYh+ljsyvwmKxMXshtJD6ITltvGNqM4SoyrrSChhp6VSNqTC32HjIp9I/O7wUbhUlmKntaZg7cZ7g2UztzPGHgJCUp3SFKuItAmAOw4oA0QuWMOBf5BcJjtPV85fgocSpucG/JGSYs06IvkSjpphhP0Gxot76eMKdvcWroBfebjCun8SEEEuSVztzi+Q2zr2cWwJklBCArpeFTNo99z1lzrMaOavmXeZsEYuiGYxHE81jJUzXZQ7g5uYgJ+kiAggkrs5tJSb40ectu9nNrdS3VYZsQR+NWVdj0kxE= 7 | jdk: 8 | - openjdk8 9 | - openjdk11 10 | after_success: 11 | - mvn cobertura:cobertura coveralls:report 12 | - echo "sonatype-nexus-snapshots\${env.REPO_USER}\${env.REPO_KEY}" > ~/settings.xml 13 | - mvn deploy --settings ~/settings.xml 14 | -------------------------------------------------------------------------------- /embedded-jms-junit/src/test/java/org/zapodot/junit/jms/EmbeddedJmsRuleSpringJmsTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit.jms; 2 | 3 | import org.hamcrest.CoreMatchers; 4 | import org.junit.Rule; 5 | import org.junit.Test; 6 | import org.springframework.jms.core.JmsOperations; 7 | import org.springframework.jms.core.JmsTemplate; 8 | 9 | import javax.jms.JMSException; 10 | import javax.jms.TextMessage; 11 | import java.util.concurrent.*; 12 | 13 | import static org.junit.Assert.assertThat; 14 | 15 | 16 | public class EmbeddedJmsRuleSpringJmsTest { 17 | 18 | private static final String TEST_MESSAGE = "Test message"; 19 | @Rule 20 | public EmbeddedJmsRule embeddedJmsRule = EmbeddedJmsRule.builder().build(); 21 | 22 | @Test 23 | public void jmsOperation() throws Exception { 24 | 25 | final JmsOperations jmsOperations = createSpringJmsOperation(); 26 | final ExecutorService executorService = Executors.newFixedThreadPool(1); 27 | try { 28 | final Future messageFuture = executorService.submit(receiveMessage(jmsOperations)); 29 | jmsOperations.convertAndSend(TEST_MESSAGE); 30 | final String message = messageFuture.get(30L, TimeUnit.SECONDS); 31 | assertThat(message, CoreMatchers.equalTo(TEST_MESSAGE)); 32 | } finally { 33 | executorService.shutdownNow(); 34 | } 35 | } 36 | 37 | private JmsOperations createSpringJmsOperation() { 38 | final JmsTemplate jmsTemplate = new JmsTemplate(embeddedJmsRule.connectionFactory()); 39 | jmsTemplate.setDefaultDestinationName(getClass().getSimpleName()); 40 | jmsTemplate.setReceiveTimeout(TimeUnit.SECONDS.toMillis(10L)); 41 | jmsTemplate.afterPropertiesSet(); 42 | return jmsTemplate; 43 | } 44 | 45 | private Callable receiveMessage(final JmsOperations jmsOperations) { 46 | return () -> { 47 | 48 | final TextMessage textMessage = (TextMessage) jmsOperations.receive(); 49 | try { 50 | return textMessage.getText(); 51 | } catch (JMSException e) { 52 | throw new IllegalStateException("Could not receive message", e); 53 | } 54 | }; 55 | } 56 | } -------------------------------------------------------------------------------- /embedded-jms-junit5/src/main/java/org/zapodot/junit5/jms/internal/BrokerConfiguration.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms.internal; 2 | 3 | import java.util.Objects; 4 | 5 | /** 6 | * BrokerConfiguration - part of the internal API. May be removed, moved or changed without prior deprecation 7 | */ 8 | public class BrokerConfiguration { 9 | 10 | public static final BrokerConfiguration DEFAULT = BrokerConfigurationBuilder.instance().withMarshal(false) 11 | .withPersistenceEnabled(false).build(); 12 | 13 | private final String name; 14 | 15 | private final Boolean marshal; 16 | 17 | private final Boolean persistenceEnabled; 18 | 19 | public BrokerConfiguration(final String name, final Boolean marshal, final Boolean persistenceEnabled) { 20 | this.name = name; 21 | this.marshal = marshal; 22 | this.persistenceEnabled = persistenceEnabled; 23 | } 24 | 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | public Boolean getMarshal() { 30 | return marshal; 31 | } 32 | 33 | public Boolean getPersistenceEnabled() { 34 | return persistenceEnabled; 35 | } 36 | 37 | @Override 38 | public boolean equals(final Object o) { 39 | if (this == o) { 40 | return true; 41 | } 42 | if (o == null || getClass() != o.getClass()) { 43 | return false; 44 | } 45 | final BrokerConfiguration that = (BrokerConfiguration) o; 46 | return Objects.equals(name, that.name) && 47 | Objects.equals(marshal, that.marshal) && 48 | Objects.equals(persistenceEnabled, that.persistenceEnabled); 49 | } 50 | 51 | @Override 52 | public int hashCode() { 53 | return Objects.hash(name, marshal, persistenceEnabled); 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | final StringBuilder sb = new StringBuilder("BrokerConfiguration{"); 59 | sb.append("name='").append(name).append('\''); 60 | sb.append(", marshal=").append(marshal); 61 | sb.append(", persistenceEnabled=").append(persistenceEnabled); 62 | sb.append('}'); 63 | return sb.toString(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/test/java/org/zapodot/junit5/jms/EmbeddedJmsBrokerPersistenceTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.junit.jupiter.api.extension.ExtendWith; 5 | import org.zapodot.junit5.jms.annotations.BrokerConfig; 6 | import org.zapodot.junit5.jms.annotations.EmbeddedJms; 7 | 8 | import javax.jms.Connection; 9 | import javax.jms.ConnectionFactory; 10 | import javax.jms.JMSException; 11 | import javax.jms.MessageProducer; 12 | import javax.jms.Queue; 13 | import javax.jms.QueueBrowser; 14 | import javax.jms.Session; 15 | import javax.jms.TextMessage; 16 | 17 | import static org.junit.jupiter.api.Assertions.assertEquals; 18 | import static org.junit.jupiter.api.Assertions.assertNotNull; 19 | 20 | @ExtendWith(EmbeddedJmsBroker.class) 21 | @BrokerConfig(persistence = "true") 22 | class EmbeddedJmsBrokerPersistenceTest { 23 | 24 | private static final String PERSISTED_MESSAGE = "PersistedMessage"; 25 | 26 | @EmbeddedJms 27 | private ConnectionFactory connectionFactory; 28 | 29 | @Test 30 | void name() throws JMSException { 31 | assertNotNull(connectionFactory); 32 | 33 | Connection connection = null; 34 | Session session = null; 35 | try { 36 | connection = connectionFactory.createConnection(); 37 | connection.start(); 38 | session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 39 | 40 | final Queue queue = session.createQueue("test.queue"); 41 | final MessageProducer producer = session.createProducer(queue); 42 | final QueueBrowser queueBrowser = session.createBrowser(queue); 43 | try { 44 | final TextMessage textMessage = session.createTextMessage(PERSISTED_MESSAGE); 45 | 46 | producer.send(textMessage); 47 | assertEquals(PERSISTED_MESSAGE, ((TextMessage) queueBrowser.getEnumeration().nextElement()).getText()); 48 | 49 | } finally { 50 | queueBrowser.close(); 51 | producer.close(); 52 | } 53 | } finally { 54 | if (session != null) { 55 | session.close(); 56 | } 57 | if (connection != null) { 58 | connection.close(); 59 | } 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /embedded-jms-junit/src/test/java/org/zapodot/junit/jms/EmbeddedJmsRuleCamelTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit.jms; 2 | 3 | import org.apache.activemq.camel.component.ActiveMQComponent; 4 | import org.apache.camel.LoggingLevel; 5 | import org.apache.camel.RoutesBuilder; 6 | import org.apache.camel.builder.RouteBuilder; 7 | import org.apache.camel.impl.JndiRegistry; 8 | import org.apache.camel.test.junit4.CamelTestSupport; 9 | import org.junit.Rule; 10 | import org.junit.Test; 11 | 12 | public class EmbeddedJmsRuleCamelTest extends CamelTestSupport { 13 | 14 | private static final String MOCK_ENDPOINT_URI = "mock:output"; 15 | private static final String JMS_DESTINATION_URI = "activemq:queue:inputQueue"; 16 | @Rule 17 | public EmbeddedJmsRule embeddedJmsRule = EmbeddedJmsRule.builder().build(); 18 | 19 | private ActiveMQComponent activeMQComponent() { 20 | final ActiveMQComponent activeMQComponent = new ActiveMQComponent(); 21 | activeMQComponent.setConnectionFactory(embeddedJmsRule.connectionFactory()); 22 | return activeMQComponent; 23 | } 24 | 25 | @Override 26 | protected JndiRegistry createRegistry() throws Exception { 27 | final JndiRegistry registry = super.createRegistry(); 28 | registry.bind("activemq", activeMQComponent()); 29 | return registry; 30 | } 31 | 32 | @Override 33 | protected RoutesBuilder createRouteBuilder() throws Exception { 34 | return new RouteBuilder() { 35 | @Override 36 | public void configure() throws Exception { 37 | from(JMS_DESTINATION_URI) 38 | .id("testRoute") 39 | .convertBodyTo(String.class) 40 | .log(LoggingLevel.INFO, "Received message ${id} with body \"${body}\"") 41 | .to(MOCK_ENDPOINT_URI); 42 | 43 | } 44 | }; 45 | } 46 | 47 | @Override 48 | public boolean isUseRouteBuilder() { 49 | return true; 50 | } 51 | 52 | @Override 53 | protected int getShutdownTimeout() { 54 | return 5; 55 | } 56 | 57 | @Test 58 | public void sendAndReceiveUsingCamel() throws Exception { 59 | 60 | final String messageBody = "Hello Camel!"; 61 | getMockEndpoint(MOCK_ENDPOINT_URI).expectedBodiesReceived(messageBody); 62 | 63 | template.sendBody(JMS_DESTINATION_URI, messageBody); 64 | 65 | assertMockEndpointsSatisfied(); 66 | 67 | } 68 | } -------------------------------------------------------------------------------- /embedded-jms-junit/src/test/java/org/zapodot/junit/jms/CallablesForSendingAndReceiving.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit.jms; 2 | 3 | import javax.jms.*; 4 | import java.lang.IllegalStateException; 5 | import java.util.concurrent.Callable; 6 | import java.util.concurrent.TimeUnit; 7 | 8 | public interface CallablesForSendingAndReceiving { 9 | 10 | static Callable messagesFromTestQueue(final ConnectionFactory connectionFactory, final String queueName) { 11 | return () -> { 12 | final Connection connection = connectionFactory.createConnection(); 13 | connection.start(); 14 | try { 15 | final Session consumerSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 16 | try { 17 | final Queue queue = consumerSession.createQueue(queueName); 18 | final MessageConsumer messageConsumer = consumerSession.createConsumer(queue); 19 | final Message message = messageConsumer.receive(TimeUnit.SECONDS.toMillis(30L)); 20 | if (message instanceof TextMessage) { 21 | return ((TextMessage) message).getText(); 22 | } else { 23 | throw new IllegalStateException("Illegal message type received"); 24 | } 25 | } finally { 26 | consumerSession.close(); 27 | } 28 | } finally { 29 | connection.close(); 30 | } 31 | }; 32 | } 33 | 34 | static Callable sendMessageToQueue(final ConnectionFactory connectionFactory, 35 | final String testQueueName, 36 | final String testMessage) throws JMSException { 37 | return () -> { 38 | final Connection connection = connectionFactory.createConnection(); 39 | connection.start(); 40 | 41 | final Session senderSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 42 | 43 | final Queue senderQueue = senderSession.createQueue(testQueueName); 44 | final MessageProducer messageProducer = senderSession.createProducer(senderQueue); 45 | final TextMessage textMessage = senderSession.createTextMessage(testMessage); 46 | messageProducer.send(textMessage); 47 | messageProducer.close(); 48 | senderSession.close(); 49 | connection.close(); 50 | return Boolean.TRUE; 51 | }; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/test/java/org/zapodot/junit5/jms/EmbeddedJmsBrokerRequestReplySpringTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms; 2 | 3 | import org.junit.jupiter.api.DisplayName; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.extension.ExtendWith; 6 | import org.springframework.jms.core.JmsOperations; 7 | import org.springframework.jms.core.JmsTemplate; 8 | import org.zapodot.junit5.jms.annotations.EmbeddedJms; 9 | 10 | import javax.jms.ConnectionFactory; 11 | import javax.jms.JMSException; 12 | import javax.jms.TextMessage; 13 | import java.util.concurrent.Callable; 14 | import java.util.concurrent.ExecutorService; 15 | import java.util.concurrent.Executors; 16 | import java.util.concurrent.Future; 17 | import java.util.concurrent.TimeUnit; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertEquals; 20 | 21 | @SuppressWarnings("squid:S00112") 22 | @ExtendWith(EmbeddedJmsBroker.class) 23 | class EmbeddedJmsBrokerRequestReplySpringTest { 24 | 25 | private static final String TEST_MESSAGE = "Test message"; 26 | 27 | private static final String DESTINATION = "queue:destination"; 28 | 29 | @EmbeddedJms 30 | private ConnectionFactory connectionFactory; 31 | 32 | @DisplayName("Request/reply using Spring JMS Template") 33 | @Test 34 | void requestReply() throws Exception { 35 | final JmsOperations jmsOperations = createJmsTemplate(); 36 | final ExecutorService executorService = Executors.newFixedThreadPool(1); 37 | try { 38 | final Future messageFuture = executorService.submit(receiveMessage(jmsOperations)); 39 | jmsOperations.convertAndSend(DESTINATION, TEST_MESSAGE); 40 | final String message = messageFuture.get(30L, TimeUnit.SECONDS); 41 | assertEquals(TEST_MESSAGE, message); 42 | } finally { 43 | executorService.shutdownNow(); 44 | } 45 | } 46 | 47 | private JmsOperations createJmsTemplate() { 48 | final JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory); 49 | jmsTemplate.afterPropertiesSet(); 50 | return jmsTemplate; 51 | } 52 | 53 | private Callable receiveMessage(final JmsOperations jmsOperations) { 54 | return () -> { 55 | 56 | final TextMessage textMessage = (TextMessage) jmsOperations.receive(DESTINATION); 57 | try { 58 | return textMessage.getText(); 59 | } catch (JMSException e) { 60 | throw new IllegalStateException("Could not receive message", e); 61 | } 62 | }; 63 | } 64 | } -------------------------------------------------------------------------------- /embedded-jms-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | embedded-jms-parent 7 | org.zapodot 8 | 0.3-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | embedded-jms-core 13 | Embedded JMS Core 14 | 15 | 16 | org.apache.activemq 17 | activemq-broker 18 | 19 | 20 | com.google.guava 21 | guava 22 | 23 | 24 | org.slf4j 25 | slf4j-api 26 | 27 | 28 | org.slf4j 29 | slf4j-simple 30 | test 31 | 32 | 33 | org.mockito 34 | mockito-junit-jupiter 35 | ${mockito.version} 36 | test 37 | 38 | 39 | org.junit.jupiter 40 | junit-jupiter-api 41 | test 42 | 43 | 44 | org.junit.jupiter 45 | junit-jupiter-engine 46 | test 47 | 48 | 49 | 50 | 51 | 52 | maven-enforcer-plugin 53 | 54 | 55 | maven-compiler-plugin 56 | 57 | 58 | maven-surefire-plugin 59 | 60 | 61 | maven-source-plugin 62 | 63 | 64 | maven-javadoc-plugin 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /embedded-jms-junit/src/test/java/org/zapodot/junit/jms/EmbeddedJmsRuleStandardSetupTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit.jms; 2 | 3 | import org.apache.activemq.ActiveMQConnectionFactory; 4 | import org.junit.Rule; 5 | import org.junit.Test; 6 | 7 | import javax.jms.*; 8 | 9 | import static org.hamcrest.CoreMatchers.equalTo; 10 | import static org.hamcrest.CoreMatchers.notNullValue; 11 | import static org.junit.Assert.assertThat; 12 | 13 | public class EmbeddedJmsRuleStandardSetupTest implements SendReceivable { 14 | 15 | private static final String TEST_QUEUE = "test.queue"; 16 | private static final String TEST_MESSAGE = "Test message"; 17 | @Rule 18 | public EmbeddedJmsRule embeddedJmsRule = EmbeddedJmsRule.builder().build(); 19 | 20 | @Test 21 | public void connectionFactory() throws Exception { 22 | 23 | final ConnectionFactory connectionFactory = embeddedJmsRule.connectionFactory(); 24 | assertThat(connectionFactory, notNullValue(ConnectionFactory.class)); 25 | } 26 | 27 | @Test 28 | public void connectAndSendAndReceive() throws Exception { 29 | final ConnectionFactory connectionFactory = embeddedJmsRule.connectionFactory(); 30 | assertThat(sendReceive(connectionFactory, TEST_QUEUE, TEST_MESSAGE), equalTo(TEST_MESSAGE)); 31 | 32 | } 33 | 34 | @Test 35 | public void usingUri() throws Exception { 36 | final ActiveMQConnectionFactory mqConnectionFactory = new ActiveMQConnectionFactory(embeddedJmsRule.brokerUri()); 37 | final Connection connection = mqConnectionFactory.createConnection(); 38 | connection.start(); 39 | try { 40 | final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 41 | try { 42 | final Queue queue = session.createQueue(TEST_QUEUE); 43 | 44 | final MessageProducer producer = session.createProducer(queue); 45 | final QueueBrowser queueBrowser = session.createBrowser(queue); 46 | try { 47 | 48 | final String text = "Fire and forget"; 49 | final TextMessage textMessage = session.createTextMessage(text); 50 | producer.send(textMessage); 51 | assertThat(((TextMessage) queueBrowser.getEnumeration().nextElement()).getText(), equalTo(text)); 52 | } finally { 53 | queueBrowser.close(); 54 | producer.close(); 55 | } 56 | 57 | } finally { 58 | session.close(); 59 | } 60 | } finally { 61 | connection.close(); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /embedded-jms-core/src/test/java/org/zapodot/jms/common/TemporaryDirectory.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.jms.common; 2 | 3 | import com.google.common.io.Files; 4 | import com.google.common.io.MoreFiles; 5 | import com.google.common.io.RecursiveDeleteOption; 6 | import org.junit.jupiter.api.extension.AfterEachCallback; 7 | import org.junit.jupiter.api.extension.ExtensionContext; 8 | import org.junit.jupiter.api.extension.ParameterContext; 9 | import org.junit.jupiter.api.extension.ParameterResolutionException; 10 | import org.junit.jupiter.api.extension.ParameterResolver; 11 | 12 | import java.io.File; 13 | import java.lang.annotation.Documented; 14 | import java.lang.annotation.ElementType; 15 | import java.lang.annotation.Retention; 16 | import java.lang.annotation.RetentionPolicy; 17 | import java.lang.annotation.Target; 18 | 19 | public class TemporaryDirectory implements ParameterResolver, AfterEachCallback { 20 | 21 | private static final ExtensionContext.Namespace STORE = ExtensionContext.Namespace.create(TemporaryDirectory.class); 22 | 23 | private static final String KEY = "tempDir"; 24 | 25 | @Target(ElementType.PARAMETER) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @Documented 28 | public @interface TempDir { 29 | } 30 | 31 | @Override 32 | public void afterEach(final ExtensionContext context) throws Exception { 33 | final File tempDir = context.getStore(STORE).remove(KEY, File.class); 34 | if (tempDir != null && tempDir.isDirectory()) { 35 | MoreFiles.deleteRecursively(tempDir.toPath(), RecursiveDeleteOption.ALLOW_INSECURE); 36 | } 37 | } 38 | 39 | @Override 40 | public boolean supportsParameter(final ParameterContext parameterContext, 41 | final ExtensionContext extensionContext) throws ParameterResolutionException { 42 | 43 | return parameterContext.isAnnotated(TempDir.class) && parameterContext.getParameter().getType() 44 | .isAssignableFrom( 45 | File.class); 46 | } 47 | 48 | @Override 49 | public Object resolveParameter(final ParameterContext parameterContext, 50 | final ExtensionContext extensionContext) throws ParameterResolutionException { 51 | return extensionContext 52 | .getStore(STORE).getOrComputeIfAbsent( 53 | KEY, key -> createTemporaryDir(), File.class); 54 | } 55 | 56 | private File createTemporaryDir() { 57 | return Files.createTempDir(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /embedded-jms-core/src/test/java/org/zapodot/jms/common/EmbeddedJMSBrokerHolderTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.jms.common; 2 | 3 | import org.apache.activemq.broker.BrokerService; 4 | import org.junit.jupiter.api.DisplayName; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertFalse; 8 | import static org.junit.jupiter.api.Assertions.assertNotNull; 9 | import static org.junit.jupiter.api.Assertions.assertThrows; 10 | import static org.junit.jupiter.api.Assertions.assertTrue; 11 | 12 | @SuppressWarnings("squid:S00112") 13 | class EmbeddedJMSBrokerHolderTest { 14 | 15 | @DisplayName("Create EmbeddedJMSBrokerHolder instance") 16 | @Test 17 | void create() throws Exception { 18 | try (final EmbeddedJMSBrokerHolder embeddedJmsBrokerHolder = EmbeddedJMSBrokerHolder 19 | .create("name", false, false)) { 20 | assertNotNull(embeddedJmsBrokerHolder.getBrokerService()); 21 | assertFalse(embeddedJmsBrokerHolder.getBrokerService().isStarted()); 22 | } 23 | } 24 | 25 | @DisplayName("Creating a broker using an illegal URI as name should fail") 26 | @Test 27 | void createFails() { 28 | assertThrows(IllegalStateException.class, () -> EmbeddedJMSBrokerHolder 29 | .create("\\\\\\", false, false)); 30 | } 31 | 32 | @DisplayName("Creates two brokers with the same name should cause the second one to fail") 33 | @Test 34 | void createDouble() { 35 | 36 | final String name = "name"; 37 | assertThrows(IllegalStateException.class, () -> { 38 | try (EmbeddedJMSBrokerHolder broker1 = EmbeddedJMSBrokerHolder.create(name, false, false)) { 39 | broker1.start(); 40 | try (EmbeddedJMSBrokerHolder broker2 = EmbeddedJMSBrokerHolder.create(name, false, false)) { 41 | broker2.start(); 42 | } 43 | } 44 | 45 | }); 46 | 47 | } 48 | 49 | @DisplayName("Create EmbeddedJMSBrokerHolder instance, start it and then stop it again") 50 | @Test 51 | @SuppressWarnings("squid:S4087") 52 | void startStop() throws Exception { 53 | try (final EmbeddedJMSBrokerHolder embeddedJmsBrokerHolder = EmbeddedJMSBrokerHolder 54 | .create("name", false, false)) { 55 | final BrokerService brokerService = embeddedJmsBrokerHolder.getBrokerService(); 56 | assertNotNull(brokerService); 57 | embeddedJmsBrokerHolder.start(); 58 | assertTrue(brokerService.isStarted()); 59 | embeddedJmsBrokerHolder.close(); 60 | assertTrue(embeddedJmsBrokerHolder.getBrokerService().isStopped()); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /embedded-jms-junit5/src/main/java/org/zapodot/junit5/jms/internal/BrokerConfigurationBuilder.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms.internal; 2 | 3 | import com.google.common.base.Strings; 4 | import org.zapodot.junit5.jms.annotations.BrokerConfig; 5 | 6 | import java.util.Optional; 7 | 8 | /** 9 | * BrokerConfigurationBuilder - part of the internal API. May be removed, moved or changed without prior deprecation 10 | */ 11 | public final class BrokerConfigurationBuilder { 12 | private String name; 13 | 14 | private Boolean marshal; 15 | 16 | private Boolean persistenceEnabled; 17 | 18 | private BrokerConfigurationBuilder() { 19 | } 20 | 21 | public static BrokerConfigurationBuilder instance() { 22 | return new BrokerConfigurationBuilder(); 23 | } 24 | 25 | public static BrokerConfigurationBuilder fromInstance(final BrokerConfiguration brokerConfiguration) { 26 | return Optional.ofNullable(brokerConfiguration) 27 | .map(b -> instance() 28 | .withName(b.getName()) 29 | .withPersistenceEnabled(b.getPersistenceEnabled()) 30 | .withMarshal(b.getMarshal())) 31 | .orElse(BrokerConfigurationBuilder.instance()); 32 | } 33 | 34 | public static BrokerConfigurationBuilder fromBrokerConfigAnnotation(BrokerConfig brokerConfig) { 35 | return instance() 36 | .withName(Strings.emptyToNull(brokerConfig.name())) 37 | .withMarshal(convertFromString(brokerConfig.marshall())) 38 | .withPersistenceEnabled(convertFromString(brokerConfig.persistence())); 39 | } 40 | 41 | public BrokerConfigurationBuilder withName(String name) { 42 | this.name = name; 43 | return this; 44 | } 45 | 46 | public BrokerConfigurationBuilder withMarshal(Boolean marshal) { 47 | this.marshal = marshal; 48 | return this; 49 | } 50 | 51 | public BrokerConfigurationBuilder withPersistenceEnabled(Boolean persistenceEnabled) { 52 | this.persistenceEnabled = persistenceEnabled; 53 | return this; 54 | } 55 | 56 | public BrokerConfigurationBuilder mergeWithBrokerConfiguration(final BrokerConfiguration brokerConfiguration) { 57 | Optional.ofNullable(brokerConfiguration) 58 | .ifPresent(b -> { 59 | withName(b.getName()); 60 | withMarshal(b.getMarshal()); 61 | withPersistenceEnabled(b.getPersistenceEnabled()); 62 | }); 63 | return this; 64 | } 65 | 66 | private static Boolean convertFromString(final String value) { 67 | return Optional.ofNullable(Strings.emptyToNull(value)).map(Boolean::valueOf).orElse(null); 68 | } 69 | 70 | public BrokerConfiguration build() { 71 | return new BrokerConfiguration(name, marshal, persistenceEnabled); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/main/java/org/zapodot/junit5/jms/internal/FieldInjector.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms.internal; 2 | 3 | import org.apache.activemq.ActiveMQConnectionFactory; 4 | import org.junit.platform.commons.util.ReflectionUtils; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.zapodot.jms.common.EmbeddedJMSBrokerHolder; 8 | 9 | import javax.jms.ConnectionFactory; 10 | import java.lang.reflect.Field; 11 | import java.net.URI; 12 | import java.util.Optional; 13 | 14 | /** 15 | * FieldInjector - part of the internal API. May be removed, moved or changed without prior deprecation 16 | */ 17 | public class FieldInjector { 18 | 19 | private static final Logger LOGGER = LoggerFactory.getLogger(FieldInjector.class); 20 | 21 | private FieldInjector() { 22 | // Constructor added to avoid instantiation 23 | } 24 | 25 | public static void injectToInstance(final Object instance, final EmbeddedJMSBrokerHolder embeddedJMSBrokerHolder) { 26 | if (instance.getClass().isMemberClass()) { 27 | tryToFindOuterInstance(instance) 28 | .ifPresent(i -> injectToInstance(i, embeddedJMSBrokerHolder)); 29 | } 30 | InjectableFieldsAccessor.findInjectableFields(instance.getClass()) 31 | .stream() 32 | .forEach(field -> injectConnectionFactoryOrURI(instance, 33 | field, 34 | embeddedJMSBrokerHolder)); 35 | } 36 | 37 | private static Optional tryToFindOuterInstance(final Object innerInstance) { 38 | return ReflectionUtils.getOutermostInstance(innerInstance, innerInstance.getClass().getDeclaringClass()); 39 | } 40 | 41 | private static void injectConnectionFactoryOrURI(final Object instance, 42 | final Field field, 43 | final EmbeddedJMSBrokerHolder embeddedJMSBrokerHolder) { 44 | boolean accessibleOriginal = field.isAccessible(); 45 | field.setAccessible(true); 46 | try { 47 | if (ActiveMQConnectionFactory.class.isAssignableFrom(field.getType())) { 48 | LOGGER.debug("Will inject org.apache.activemq.ActiveMQConnectionFactory to field \"{}\"", 49 | field.getName()); 50 | field.set(instance, embeddedJMSBrokerHolder.getActiveMQConnectionFactory()); 51 | } else if (ConnectionFactory.class.isAssignableFrom(field.getType())) { 52 | LOGGER.debug("Will inject javax.jms.ConnectionFactory to field \"{}\"", field.getName()); 53 | field.set(instance, embeddedJMSBrokerHolder.getConnectionFactory()); 54 | } else if (URI.class.isAssignableFrom(field.getType())) { 55 | LOGGER.debug("Will inject java.net.URI to field \"{}\"", field.getName()); 56 | field.set(instance, embeddedJMSBrokerHolder.getBrokerUri()); 57 | } 58 | 59 | } catch (IllegalAccessException | IllegalArgumentException e) { 60 | throw new IllegalStateException( 61 | "Could not inject embedded javax.jms.ConnectionFactory, ActiveMQConnectionFactory or URI to field", 62 | e); 63 | } finally { 64 | field.setAccessible(accessibleOriginal); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /embedded-jms-junit/src/main/java/org/zapodot/junit/jms/impl/EmbeddedJmsRuleImpl.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit.jms.impl; 2 | 3 | import org.apache.activemq.ActiveMQConnectionFactory; 4 | import org.junit.runner.Description; 5 | import org.junit.runners.model.Statement; 6 | import org.zapodot.jms.common.EmbeddedJMSBrokerHolder; 7 | import org.zapodot.junit.jms.EmbeddedJmsRule; 8 | 9 | import javax.jms.ConnectionFactory; 10 | import java.net.URI; 11 | 12 | /** 13 | * Implementation. Part of the internal API 14 | */ 15 | public class EmbeddedJmsRuleImpl implements EmbeddedJmsRule { 16 | 17 | private final String predefinedName; 18 | private final boolean marshal; 19 | private final boolean persistent; 20 | 21 | private EmbeddedJMSBrokerHolder jmsBrokerHolder; 22 | 23 | public EmbeddedJmsRuleImpl(final String predefinedName, final boolean marshal, final boolean persistent) { 24 | this.predefinedName = predefinedName; 25 | this.marshal = marshal; 26 | this.persistent = persistent; 27 | } 28 | 29 | @Override 30 | public ConnectionFactory connectionFactory() { 31 | return activeMqConnectionFactory(); 32 | } 33 | 34 | @Override 35 | public ActiveMQConnectionFactory activeMqConnectionFactory() { 36 | if (jmsBrokerHolder == null) { 37 | throw new IllegalStateException("Can not create ConnectionFactory before the broker has started"); 38 | } else { 39 | return jmsBrokerHolder.getActiveMQConnectionFactory(); 40 | } 41 | } 42 | 43 | @Override 44 | public URI brokerUri() { 45 | if (jmsBrokerHolder == null) { 46 | throw new IllegalStateException("Can not create broker URI before the broker has started"); 47 | } else { 48 | return jmsBrokerHolder.getBrokerUri(); 49 | } 50 | } 51 | 52 | @Override 53 | public Statement apply(final Statement base, final Description description) { 54 | return new Statement() { 55 | @Override 56 | public void evaluate() throws Throwable { 57 | startService(getBrokerName(description)); 58 | try { 59 | base.evaluate(); 60 | } finally { 61 | stopService(); 62 | } 63 | } 64 | }; 65 | } 66 | 67 | private String getBrokerName(final Description description) { 68 | if (predefinedName == null) { 69 | return extractNameFromDescription(description); 70 | } else { 71 | return predefinedName; 72 | } 73 | } 74 | 75 | private String extractNameFromDescription(final Description description) { 76 | return description.getTestClass() == null ? description.getClassName() : description.getTestClass() 77 | .getSimpleName(); 78 | } 79 | 80 | private void startService(final String name) { 81 | try { 82 | jmsBrokerHolder = EmbeddedJMSBrokerHolder.create(name, marshal, persistent); 83 | jmsBrokerHolder.start(); 84 | } catch (Exception e) { 85 | throw new IllegalStateException("Could not start broker", e); 86 | } 87 | } 88 | 89 | private void stopService() { 90 | try { 91 | jmsBrokerHolder.close(); 92 | } catch (Exception e) { 93 | throw new IllegalStateException("Could not stop broker", e); 94 | } 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at team@zapodot.org. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /embedded-jms-junit5/src/test/java/org/zapodot/junit5/jms/EmbeddedJmsBrokerCamelTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms; 2 | 3 | import org.apache.activemq.ActiveMQConnectionFactory; 4 | import org.apache.activemq.camel.component.ActiveMQComponent; 5 | import org.apache.camel.LoggingLevel; 6 | import org.apache.camel.ProducerTemplate; 7 | import org.apache.camel.builder.RouteBuilder; 8 | import org.apache.camel.component.mock.MockEndpoint; 9 | import org.apache.camel.impl.DefaultCamelContext; 10 | import org.apache.camel.management.JmxSystemPropertyKeys; 11 | import org.junit.jupiter.api.AfterEach; 12 | import org.junit.jupiter.api.BeforeEach; 13 | import org.junit.jupiter.api.Test; 14 | import org.junit.jupiter.api.extension.ExtendWith; 15 | import org.zapodot.junit5.jms.annotations.BrokerConfig; 16 | import org.zapodot.junit5.jms.annotations.EmbeddedJms; 17 | 18 | import java.util.concurrent.TimeUnit; 19 | 20 | import static org.junit.jupiter.api.Assertions.assertNotNull; 21 | 22 | @BrokerConfig(persistence = "false") 23 | @ExtendWith(EmbeddedJmsBroker.class) 24 | class EmbeddedJmsBrokerCamelTest { 25 | 26 | private static final String MOCK_ENDPOINT_URI = "mock:output"; 27 | 28 | private static final String JMS_DESTINATION_URI = "activemq:queue:inputQueue"; 29 | 30 | @EmbeddedJms 31 | private ActiveMQConnectionFactory activeMQConnectionFactory; 32 | 33 | private DefaultCamelContext camelContext; 34 | 35 | private String defaultCamelJmxSetting; 36 | 37 | @BeforeEach 38 | public void setup() throws Exception { 39 | final ActiveMQComponent activeMQComponent = new ActiveMQComponent(); 40 | activeMQComponent.setConnectionFactory(activeMQConnectionFactory); 41 | activeMQComponent.setUseSingleConnection(true); 42 | activeMQComponent.setTransacted(false); 43 | 44 | this.defaultCamelJmxSetting = System.getProperty(JmxSystemPropertyKeys.DISABLED); 45 | System.setProperty(JmxSystemPropertyKeys.DISABLED, Boolean.TRUE.toString()); 46 | 47 | this.camelContext = new DefaultCamelContext(); 48 | this.camelContext.addComponent("activemq", activeMQComponent); 49 | camelContext.setName(EmbeddedJmsBrokerCamelTest.class.getSimpleName() + "Context"); 50 | 51 | try { 52 | this.camelContext.addRoutes(new RouteBuilder() { 53 | @Override 54 | public void configure() { 55 | from(JMS_DESTINATION_URI) 56 | .id(EmbeddedJmsBrokerCamelTest.class.getSimpleName()) 57 | .convertBodyTo(String.class) 58 | .log(LoggingLevel.INFO, "Received message ${id} with body \"${body}\"") 59 | .to(MOCK_ENDPOINT_URI); 60 | } 61 | }); 62 | this.camelContext.start(); 63 | } catch (Exception e) { 64 | if (this.camelContext.isStarted()) { 65 | this.camelContext.stop(); 66 | } 67 | } 68 | 69 | 70 | } 71 | 72 | @Test 73 | void jmsUsingCamel() throws Exception { 74 | final String messageBody = "Hello Camel!"; 75 | assertNotNull(camelContext); 76 | 77 | final MockEndpoint mockEndpoint = camelContext.getEndpoint(MOCK_ENDPOINT_URI, MockEndpoint.class); 78 | mockEndpoint.expectedBodiesReceived(messageBody); 79 | 80 | final ProducerTemplate template = camelContext.createProducerTemplate(); 81 | template.start(); 82 | template.sendBody(JMS_DESTINATION_URI, messageBody); 83 | 84 | MockEndpoint.assertIsSatisfied(camelContext, 1L, TimeUnit.MINUTES); 85 | } 86 | 87 | @AfterEach 88 | public void tearDown() throws Exception { 89 | this.camelContext.stop(); 90 | if (defaultCamelJmxSetting != null) { 91 | System.setProperty(JmxSystemPropertyKeys.DISABLED, defaultCamelJmxSetting); 92 | } 93 | } 94 | 95 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | embedded-jms-junit 2 | ================= 3 | 4 | [![Build Status](https://github.com/zapodot/embedded-jms-junit/workflows/Java%20CI/badge.svg)](https://github.com/zapodot/embedded-jms-junit/actions?query=workflow%3A%22Java+CI%22) 5 | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.zapodot/embedded-jms-junit/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.zapodot/embedded-jms-junit) 6 | [![Apache V2 License](http://img.shields.io/badge/license-Apache%20V2-blue.svg)](//github.com/zapodot/embedded-jms-junit/blob/master/LICENSE) 7 | [![Libraries.io for GitHub](https://img.shields.io/librariesio/github/zapodot/embedded-jms-junit.svg)](https://libraries.io/github/zapodot/embedded-db-junit) 8 | [![Coverage Status](https://coveralls.io/repos/github/zapodot/embedded-jms-junit/badge.svg?branch=master)](https://coveralls.io/github/zapodot/embedded-jms-junit?branch=master) 9 | [![DepShield Badge](https://depshield.sonatype.org/badges/zapodot/embedded-jms-junit/depshield.svg)](https://depshield.github.io) 10 | 11 | [JUnit](http://junit.org/) extension that provides a [ActiveMQ Embedded in-memory JMS Broker](http://activemq.apache.org/). 12 | It should be compatible with all the usual JMS integration tools such as Apache Camel and Spring JMS Template. Inspired by the [Embedded DB JUnit Rule](//github.com/zapodot/embedded-db-junit) project. 13 | 14 | ## Why? 15 | * because you want to test your JMS integration code without being dependent on a running external JMS Broker 16 | * setting up the broker manually for all your tests requires a lot of boilerplate code 17 | * I found myself repeating myself and decided that creating this library would make my life easier :-) 18 | 19 | ## Status 20 | This library is distributed through the [Sonatype OSS repo](https://oss.sonatype.org/) and should thus be widely available. Java 8 or higher is required. 21 | Feedback is more than welcome. Feel free to create issues if you find bugs or have feature requests for future releases :-) 22 | 23 | ## Changelog 24 | * version 0.2: rewritten core and added support for JUnit 5 Jupiter 25 | * version 0.1: initial release 26 | 27 | # Usage 28 | ## JUnit 5 (v. 0.2+) 29 | More information on JMS support is found in the [project WIKI](//github.com/zapodot/embedded-jms-junit/wiki/Using-with-JUnit-5-Jupiter) 30 | ### Add dependency 31 | ```xml 32 | 33 | org.zapodot 34 | embedded-jms-junit5 35 | 0.2 36 | test 37 | 38 | ``` 39 | ### Use ExtendWith to enable the extension and inject the connection factory using @EmbeddedJms 40 | ```java 41 | @ExtendWith(EmbeddedJmsBroker.class) 42 | class EmbeddedJmsBrokerRequestReplySpringTest { 43 | 44 | private static final String TEST_MESSAGE = "Test message"; 45 | 46 | private static final String DESTINATION = "queue:destination"; 47 | 48 | /** 49 | * The type of property must be either ConnectionFactory, ActiveMQFactory or URI. 50 | * If it is a URI to the broker is injected 51 | */ 52 | @EmbeddedJms 53 | private ConnectionFactory connectionFactory; 54 | 55 | @DisplayName("My test") 56 | @Test 57 | void testJmsLogic() throws Exception { 58 | // make JMS magic 59 | } 60 | 61 | @DisplayName("parameterized test") 62 | @Test 63 | void connectionFactoryParameter(@EmbeddedJms ConnectionFactory connectionFactory) { 64 | // perform JMS magic 65 | } 66 | 67 | } 68 | ``` 69 | ## JUnit 4 70 | ### Add dependency 71 | ```xml 72 | 73 | org.zapodot 74 | embedded-jms-junit 75 | 0.2 76 | test 77 | 78 | ``` 79 | 80 | ### Add to JUnit4 test 81 | ```java 82 | @Rule 83 | public EmbeddedJmsRule embeddedJmsRule = EmbeddedJmsRule.builder().build(); 84 | 85 | @Test 86 | public void jmsTest() throws Exception { 87 | final ConnectionFactory connectionFactory = embeddedJmsRule.connectionFactory(); 88 | 89 | // work your JMS magic 90 | 91 | } 92 | ``` 93 | For more examples check the JUnit tests in this project 94 | -------------------------------------------------------------------------------- /embedded-jms-junit/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | org.zapodot 7 | embedded-jms-parent 8 | 0.3-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | embedded-jms-junit 13 | Embedded JMS JUnit4 @Rule 14 | 15 | 16 | 17 | org.zapodot 18 | embedded-jms-core 19 | 20 | 21 | org.slf4j 22 | slf4j-api 23 | 24 | 25 | junit 26 | junit 27 | 28 | 29 | org.apache.activemq 30 | activemq-broker 31 | 32 | 33 | com.google.guava 34 | guava 35 | 36 | 37 | 38 | org.junit.vintage 39 | junit-vintage-engine 40 | test 41 | 42 | 43 | org.slf4j 44 | jcl-over-slf4j 45 | test 46 | 47 | 48 | org.slf4j 49 | slf4j-simple 50 | test 51 | 52 | 53 | org.springframework 54 | spring-jms 55 | test 56 | 57 | 58 | org.apache.camel 59 | camel-test 60 | test 61 | 62 | 63 | org.apache.activemq 64 | activemq-camel 65 | test 66 | 67 | 68 | 69 | 70 | 71 | maven-enforcer-plugin 72 | 73 | 74 | maven-compiler-plugin 75 | 76 | 77 | maven-surefire-plugin 78 | 79 | 80 | maven-source-plugin 81 | 82 | 83 | maven-javadoc-plugin 84 | 85 | 86 | org.eluder.coveralls 87 | coveralls-maven-plugin 88 | 89 | 90 | org.codehaus.mojo 91 | cobertura-maven-plugin 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | java9plus 100 | 101 | [9,) 102 | 103 | 104 | 105 | javax.activation 106 | javax.activation-api 107 | ${javax.activation-api.version} 108 | test 109 | 110 | 111 | javax.xml.bind 112 | jaxb-api 113 | ${javax.xml.bind.jaxb-api.version} 114 | test 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /embedded-jms-junit5/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | org.zapodot 7 | embedded-jms-parent 8 | 0.3-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | embedded-jms-junit5 13 | Embedded JMS JUnit5 Jupiter Extension 14 | 15 | 16 | org.zapodot 17 | embedded-jms-core 18 | 19 | 20 | org.slf4j 21 | slf4j-api 22 | 23 | 24 | com.google.guava 25 | guava 26 | 27 | 28 | org.apache.activemq 29 | activemq-broker 30 | 31 | 32 | org.junit.jupiter 33 | junit-jupiter-api 34 | 35 | 36 | org.junit.jupiter 37 | junit-jupiter-engine 38 | 39 | 40 | org.apache.activemq 41 | activemq-kahadb-store 42 | test 43 | 44 | 45 | org.slf4j 46 | jcl-over-slf4j 47 | test 48 | 49 | 50 | org.springframework 51 | spring-jms 52 | test 53 | 54 | 55 | org.apache.camel 56 | camel-core 57 | ${camel.version} 58 | 59 | 60 | org.apache.activemq 61 | activemq-camel 62 | test 63 | 64 | 65 | org.slf4j 66 | slf4j-simple 67 | test 68 | 69 | 70 | 71 | 72 | 73 | maven-enforcer-plugin 74 | 75 | 76 | maven-compiler-plugin 77 | 78 | 79 | maven-surefire-plugin 80 | 81 | 82 | maven-source-plugin 83 | 84 | 85 | maven-javadoc-plugin 86 | 87 | 88 | org.eluder.coveralls 89 | coveralls-maven-plugin 90 | 91 | 92 | org.codehaus.mojo 93 | cobertura-maven-plugin 94 | 95 | 96 | 97 | 98 | 99 | 100 | java9plus 101 | 102 | [9,) 103 | 104 | 105 | 106 | javax.activation 107 | javax.activation-api 108 | ${javax.activation-api.version} 109 | test 110 | 111 | 112 | javax.xml.bind 113 | jaxb-api 114 | ${javax.xml.bind.jaxb-api.version} 115 | test 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /embedded-jms-core/src/main/java/org/zapodot/jms/common/EmbeddedJMSBrokerHolder.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.jms.common; 2 | 3 | import com.google.common.base.Preconditions; 4 | import com.google.common.io.Files; 5 | import com.google.common.io.MoreFiles; 6 | import com.google.common.io.RecursiveDeleteOption; 7 | import org.apache.activemq.ActiveMQConnectionFactory; 8 | import org.apache.activemq.broker.BrokerService; 9 | import org.apache.activemq.store.memory.MemoryPersistenceAdapter; 10 | import org.apache.activemq.transport.TransportServer; 11 | import org.apache.activemq.transport.vm.VMTransportFactory; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | 15 | import javax.jms.ConnectionFactory; 16 | import java.io.File; 17 | import java.io.IOException; 18 | import java.net.URI; 19 | import java.net.URISyntaxException; 20 | 21 | /** 22 | * Internal API. May be removed, moved or changed without prior deprecation 23 | */ 24 | public class EmbeddedJMSBrokerHolder implements AutoCloseable, ConnectionFactoryAccessor, ActiveMQConnectionFactoryAccessor, BrokerURIAccessor { 25 | private static final Logger LOGGER = LoggerFactory.getLogger(EmbeddedJMSBrokerHolder.class); 26 | 27 | private final BrokerService brokerService; 28 | 29 | private final File tempDir; 30 | 31 | EmbeddedJMSBrokerHolder(final BrokerService brokerService, final File tempDir) { 32 | Preconditions.checkNotNull(brokerService); 33 | this.brokerService = brokerService; 34 | 35 | Preconditions.checkNotNull(tempDir); 36 | this.tempDir = tempDir; 37 | } 38 | 39 | public BrokerService getBrokerService() { 40 | return brokerService; 41 | } 42 | 43 | @Override 44 | public ConnectionFactory getConnectionFactory() { 45 | return getActiveMQConnectionFactory(); 46 | } 47 | 48 | @Override 49 | public ActiveMQConnectionFactory getActiveMQConnectionFactory() { 50 | return new ActiveMQConnectionFactory(brokerService.getVmConnectorURI()); 51 | } 52 | 53 | @Override 54 | public URI getBrokerUri() { 55 | return brokerService.getVmConnectorURI(); 56 | } 57 | 58 | public static EmbeddedJMSBrokerHolder create(final String name, boolean marshal, boolean persistent) { 59 | final File tempDir = Files.createTempDir(); 60 | LOGGER.debug("Created temporary directory: \"{}\"", tempDir.getAbsolutePath()); 61 | return new EmbeddedJMSBrokerHolder(createAndConfigureBrokerService(new BrokerSettings(name, 62 | marshal, 63 | persistent, 64 | tempDir)), tempDir); 65 | } 66 | 67 | private static BrokerService createAndConfigureBrokerService(final BrokerSettings brokerSettings) { 68 | return configureBrokerService(new BrokerService(), brokerSettings); 69 | } 70 | 71 | static BrokerService configureBrokerService(final BrokerService brokerService, 72 | final BrokerSettings brokerSettings) { 73 | Preconditions.checkNotNull(brokerService); 74 | Preconditions.checkNotNull(brokerSettings); 75 | brokerService.setBrokerName(brokerSettings.getName()); 76 | brokerService.setStartAsync(false); 77 | brokerService.setPersistent(brokerSettings.isPersistent()); 78 | brokerService.setUseJmx(false); 79 | brokerService.setDataDirectoryFile(brokerSettings.getTempDir()); 80 | brokerService.setUseShutdownHook(false); 81 | try { 82 | if (brokerSettings.isPersistent()) { 83 | brokerService.setPersistenceAdapter(new MemoryPersistenceAdapter()); 84 | } 85 | } catch (IOException e) { 86 | throw new IllegalStateException("Could not enable the MemoryPersistenceAdapter"); 87 | } 88 | try { 89 | brokerService.addConnector(createVmTransportServer(createVmTransportUri(brokerSettings.getName(), 90 | brokerSettings.isMarshal()))); 91 | } catch (Exception e) { 92 | throw new IllegalStateException("Could not create VM Transport URI", e); 93 | } 94 | return brokerService; 95 | } 96 | 97 | private static TransportServer createVmTransportServer(final URI vmUri) { 98 | try { 99 | return new VMTransportFactory().doBind(vmUri); 100 | } catch (IOException e) { 101 | throw new IllegalStateException("Could not setup VM transport", e); 102 | } 103 | } 104 | 105 | private static URI createVmTransportUri(final String name, final boolean marshal) { 106 | try { 107 | return new URI(String.format("vm://%s?marshal=%s", name, marshal)); 108 | } catch (URISyntaxException e) { 109 | throw new IllegalStateException("Could not create an URI for the VM Transport", e); 110 | } 111 | } 112 | 113 | public void start() { 114 | try { 115 | brokerService.start(true); 116 | } catch (Exception e) { 117 | throw new IllegalStateException("Could not start the embedded JMS broker", e); 118 | } 119 | } 120 | 121 | @Override 122 | public void close() throws Exception { 123 | try { 124 | brokerService.stop(); 125 | } finally { 126 | if (tempDir.isDirectory()) { 127 | MoreFiles.deleteRecursively(tempDir.toPath(), RecursiveDeleteOption.ALLOW_INSECURE); 128 | } 129 | } 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /embedded-jms-core/src/test/java/org/zapodot/jms/common/EmbeddedJMSBrokerHolderConfigurerTest.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.jms.common; 2 | 3 | import com.google.common.io.Files; 4 | import com.google.common.io.MoreFiles; 5 | import com.google.common.io.RecursiveDeleteOption; 6 | import org.apache.activemq.broker.BrokerService; 7 | import org.apache.activemq.store.PersistenceAdapter; 8 | import org.apache.activemq.transport.TransportServer; 9 | import org.junit.jupiter.api.DisplayName; 10 | import org.junit.jupiter.api.Nested; 11 | import org.junit.jupiter.api.Test; 12 | import org.junit.jupiter.api.extension.ExtendWith; 13 | import org.mockito.ArgumentCaptor; 14 | import org.mockito.Mock; 15 | import org.mockito.junit.jupiter.MockitoExtension; 16 | 17 | import java.io.File; 18 | import java.io.IOException; 19 | 20 | import static org.junit.jupiter.api.Assertions.assertFalse; 21 | import static org.junit.jupiter.api.Assertions.assertNotNull; 22 | import static org.junit.jupiter.api.Assertions.assertThrows; 23 | import static org.mockito.ArgumentMatchers.isA; 24 | import static org.mockito.Mockito.*; 25 | import static org.mockito.Mockito.eq; 26 | 27 | @DisplayName("EmbeddedJMSBrokerHolder") 28 | @ExtendWith(TemporaryDirectory.class) 29 | @ExtendWith(MockitoExtension.class) 30 | class EmbeddedJMSBrokerHolderConfigurerTest { 31 | 32 | @DisplayName("when configured") 33 | @Nested 34 | class Configure { 35 | 36 | @DisplayName("with persistence disabled") 37 | @Test 38 | void configureBrokerService(@Mock final BrokerService brokerService, 39 | @TemporaryDirectory.TempDir final File tempDir) throws Exception { 40 | final BrokerSettings brokerSettings = new BrokerSettings("name", false, false, tempDir); 41 | final BrokerService configuredService = EmbeddedJMSBrokerHolder.configureBrokerService(brokerService, 42 | brokerSettings); 43 | assertNotNull(configuredService); 44 | 45 | verify(brokerService, never()).setPersistenceAdapter(isA(PersistenceAdapter.class)); 46 | verify(brokerService).setBrokerName(eq(brokerSettings.getName())); 47 | verify(brokerService).setUseShutdownHook(eq(false)); 48 | verify(brokerService).setUseJmx(eq(false)); 49 | verify(brokerService).setPersistent(eq(false)); 50 | verify(brokerService).setStartAsync(eq(false)); 51 | verify(brokerService).setDataDirectoryFile(eq(tempDir)); 52 | // Need to clean up after testing by shutting down TransportServer 53 | final ArgumentCaptor transportServerArgumentCaptor = ArgumentCaptor 54 | .forClass(TransportServer.class); 55 | verify(brokerService).addConnector(transportServerArgumentCaptor.capture()); 56 | transportServerArgumentCaptor.getValue().stop(); 57 | verifyNoMoreInteractions(brokerService); 58 | } 59 | 60 | @DisplayName("with persistence enabled") 61 | @Test 62 | void configureBrokerServicePersistenceEnabled(@Mock final BrokerService brokerService, 63 | @TemporaryDirectory.TempDir final File tempDir) throws Exception { 64 | final BrokerSettings brokerSettings = new BrokerSettings("name", false, true, tempDir); 65 | assertNotNull(EmbeddedJMSBrokerHolder.configureBrokerService(brokerService, 66 | brokerSettings)); 67 | 68 | // Need to clean up after testing by shutting down PersistenceAdapter 69 | final ArgumentCaptor persistenceAdapterArgumentCaptor = ArgumentCaptor 70 | .forClass(PersistenceAdapter.class); 71 | verify(brokerService, times(1)).setPersistenceAdapter(persistenceAdapterArgumentCaptor.capture()); 72 | persistenceAdapterArgumentCaptor.getValue().stop(); 73 | 74 | // Need to clean up after testing by shutting down TransportServer 75 | final ArgumentCaptor transportServerArgumentCaptor = ArgumentCaptor 76 | .forClass(TransportServer.class); 77 | verify(brokerService, times(1)).addConnector(transportServerArgumentCaptor.capture()); 78 | transportServerArgumentCaptor.getValue().stop(); 79 | verify(brokerService).setBrokerName(eq(brokerSettings.getName())); 80 | verify(brokerService).setUseShutdownHook(eq(false)); 81 | verify(brokerService).setUseJmx(eq(false)); 82 | verify(brokerService).setPersistent(eq(brokerSettings.isPersistent())); 83 | verify(brokerService).setStartAsync(eq(false)); 84 | verify(brokerService).setDataDirectoryFile(eq(tempDir)); 85 | verifyNoMoreInteractions(brokerService); 86 | } 87 | 88 | @DisplayName("with persistence enabled but an IOException occurs") 89 | @Test 90 | void configureBrokerServicePersistentFails(@Mock final BrokerService brokerService, 91 | @TemporaryDirectory.TempDir final File tempDir) throws Exception { 92 | doThrow(new IOException("I/O failure")).when(brokerService) 93 | .setPersistenceAdapter(isA(PersistenceAdapter.class)); 94 | final BrokerSettings brokerSettings = new BrokerSettings("name", false, true, tempDir); 95 | assertThrows(IllegalStateException.class, 96 | () -> EmbeddedJMSBrokerHolder.configureBrokerService(brokerService, 97 | brokerSettings)); 98 | // Need to clean up after testing by shutting down PersistenceAdapter 99 | final ArgumentCaptor persistenceAdapterArgumentCaptor = ArgumentCaptor 100 | .forClass(PersistenceAdapter.class); 101 | verify(brokerService, times(1)).setPersistenceAdapter(persistenceAdapterArgumentCaptor.capture()); 102 | persistenceAdapterArgumentCaptor.getValue().stop(); 103 | verify(brokerService).setBrokerName(eq(brokerSettings.getName())); 104 | verify(brokerService).setUseShutdownHook(eq(false)); 105 | verify(brokerService).setUseJmx(eq(false)); 106 | verify(brokerService).setPersistent(eq(brokerSettings.isPersistent())); 107 | verify(brokerService).setStartAsync(eq(false)); 108 | verify(brokerService).setDataDirectoryFile(eq(tempDir)); 109 | verifyNoMoreInteractions(brokerService); 110 | 111 | } 112 | } 113 | 114 | @DisplayName("fails to start") 115 | @Test 116 | void startFails(@Mock final BrokerService brokerService, 117 | @TemporaryDirectory.TempDir final File tempDir) throws Exception { 118 | doThrow(new IOException("IO failure")).when(brokerService).start(eq(true)); 119 | final EmbeddedJMSBrokerHolder embeddedJMSBrokerHolder = new EmbeddedJMSBrokerHolder(brokerService, tempDir); 120 | assertThrows(IllegalStateException.class, () -> embeddedJMSBrokerHolder.start()); 121 | 122 | verify(brokerService).start(eq(true)); 123 | // Need to clean up after testing by shutting down TransportServer 124 | verifyNoMoreInteractions(brokerService); 125 | } 126 | 127 | @DisplayName("starts and stops successfully") 128 | @Test 129 | void startStopSucceeds(@Mock final BrokerService brokerService, 130 | @TemporaryDirectory.TempDir final File tempDir) throws Exception { 131 | try (final EmbeddedJMSBrokerHolder embeddedJMSBrokerHolder = new EmbeddedJMSBrokerHolder(brokerService, 132 | tempDir)) { 133 | assertNotNull(embeddedJMSBrokerHolder); 134 | embeddedJMSBrokerHolder.start(); 135 | } 136 | assertFalse(tempDir.exists()); 137 | verify(brokerService).start(eq(true)); 138 | verify(brokerService).stop(); 139 | verifyNoMoreInteractions(brokerService); 140 | } 141 | 142 | @DisplayName("starts and stops successfully even though the temp dir has been removed") 143 | @Test 144 | void startStopTempDirRemoved(@Mock final BrokerService brokerService) throws Exception { 145 | final File tempDir = Files.createTempDir(); 146 | MoreFiles.deleteRecursively(tempDir.toPath(), RecursiveDeleteOption.ALLOW_INSECURE); 147 | try (final EmbeddedJMSBrokerHolder embeddedJMSBrokerHolder = new EmbeddedJMSBrokerHolder(brokerService, 148 | tempDir)) { 149 | assertNotNull(embeddedJMSBrokerHolder); 150 | embeddedJMSBrokerHolder.start(); 151 | } 152 | verify(brokerService).start(eq(true)); 153 | verify(brokerService).stop(); 154 | verifyNoMoreInteractions(brokerService); 155 | } 156 | } -------------------------------------------------------------------------------- /embedded-jms-junit5/src/main/java/org/zapodot/junit5/jms/EmbeddedJmsBroker.java: -------------------------------------------------------------------------------- 1 | package org.zapodot.junit5.jms; 2 | 3 | import com.google.common.base.Strings; 4 | import org.apache.activemq.ActiveMQConnectionFactory; 5 | import org.junit.jupiter.api.extension.AfterEachCallback; 6 | import org.junit.jupiter.api.extension.BeforeEachCallback; 7 | import org.junit.jupiter.api.extension.ExtensionContext; 8 | import org.junit.jupiter.api.extension.ParameterContext; 9 | import org.junit.jupiter.api.extension.ParameterResolver; 10 | import org.junit.jupiter.api.extension.TestInstancePostProcessor; 11 | import org.junit.platform.commons.util.AnnotationUtils; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.zapodot.jms.common.EmbeddedJMSBrokerHolder; 15 | import org.zapodot.junit5.jms.annotations.BrokerConfig; 16 | import org.zapodot.junit5.jms.annotations.EmbeddedJms; 17 | import org.zapodot.junit5.jms.internal.BrokerConfiguration; 18 | import org.zapodot.junit5.jms.internal.BrokerConfigurationBuilder; 19 | import org.zapodot.junit5.jms.internal.FieldInjector; 20 | 21 | import javax.jms.ConnectionFactory; 22 | import java.lang.annotation.Annotation; 23 | import java.lang.reflect.AnnotatedElement; 24 | import java.lang.reflect.Parameter; 25 | import java.net.URI; 26 | import java.util.Optional; 27 | 28 | /** 29 | * A JUnit 5 Jupiter Extension for running an embedded Apache ActiveMQ JMS broker for testing purposes. 30 | */ 31 | public class EmbeddedJmsBroker implements BeforeEachCallback, AfterEachCallback, TestInstancePostProcessor, ParameterResolver { 32 | 33 | private static final Logger LOGGER = LoggerFactory.getLogger(EmbeddedJmsBroker.class); 34 | 35 | private static final ExtensionContext.Namespace EMBEDDED_JMS_EXT = ExtensionContext.Namespace 36 | .create("org.zapodot.junit5.jms"); 37 | 38 | private static final String TEST_INSTANCE = "TestInstance"; 39 | 40 | private static final String STORE_EMBEDDED_JMS_BROKER = "EmbeddedJmsBroker"; 41 | 42 | private static final String STORE_BROKER_CONFIGURATION = "BrokerConfiguration"; 43 | 44 | private static EmbeddedJMSBrokerHolder getOrCreateEmbeddedJMSBrokerHolder(final ExtensionContext context) { 45 | EmbeddedJMSBrokerHolder embeddedJmsBrokerHolder = context.getStore(EMBEDDED_JMS_EXT) 46 | .get(STORE_EMBEDDED_JMS_BROKER, 47 | EmbeddedJMSBrokerHolder.class); 48 | if (embeddedJmsBrokerHolder == null) { 49 | embeddedJmsBrokerHolder = createEmbeddedJmsBrokerHolderOrDefault(context, 50 | context.getStore(EMBEDDED_JMS_EXT).get( 51 | STORE_BROKER_CONFIGURATION, 52 | BrokerConfiguration.class)); 53 | context.getStore(EMBEDDED_JMS_EXT).put(STORE_EMBEDDED_JMS_BROKER, embeddedJmsBrokerHolder); 54 | } 55 | return embeddedJmsBrokerHolder; 56 | } 57 | 58 | private static EmbeddedJMSBrokerHolder createEmbeddedJmsBrokerHolderOrDefault(final ExtensionContext extensionContext, 59 | final BrokerConfiguration brokerConfiguration) { 60 | return createEmbeddedJmsBrokerHolder( 61 | extensionContext, brokerConfiguration) 62 | .orElseGet(() -> EmbeddedJMSBrokerHolder 63 | .create(extractNameFromExtensionContext(extensionContext), false, false)); 64 | } 65 | 66 | private static Optional createBrokerConfigurationFromContext(final ExtensionContext extensionContext) { 67 | return findAnnotation(extensionContext.getElement(), BrokerConfig.class) 68 | .map(BrokerConfigurationBuilder::fromBrokerConfigAnnotation) 69 | .map(BrokerConfigurationBuilder::build); 70 | 71 | } 72 | 73 | private static Optional createEmbeddedJmsBrokerHolder(final ExtensionContext extensionContext, 74 | final BrokerConfiguration brokerConfiguration) { 75 | LOGGER.debug("Constructing broker using configuration \"{}\"", brokerConfiguration); 76 | return Optional.ofNullable(brokerConfiguration) 77 | .map(b -> createEmbeddedJMSBrokerHolderFromBrokerConfig(b, 78 | extractNameFromExtensionContext( 79 | extensionContext))); 80 | 81 | } 82 | 83 | private static String extractNameFromExtensionContext(final ExtensionContext extensionContext) { 84 | return extensionContext.getTestClass().map(Class::getSimpleName).orElse(extensionContext.getUniqueId()); 85 | } 86 | 87 | private static EmbeddedJMSBrokerHolder createEmbeddedJMSBrokerHolderFromBrokerConfig(final BrokerConfiguration brokerConfig, 88 | String nameFromTest) { 89 | final Boolean marshall = Optional.ofNullable(brokerConfig.getMarshal()).orElse(Boolean.FALSE); 90 | final Boolean persistence = Optional.ofNullable(brokerConfig.getPersistenceEnabled()).orElse(Boolean.FALSE); 91 | final String name = Optional.ofNullable(brokerConfig.getName()) 92 | .filter(n -> !Strings.isNullOrEmpty(n)) 93 | .orElse(nameFromTest); 94 | LOGGER.info("Creating an embedded JMS broker using name \"{}\"", name); 95 | return EmbeddedJMSBrokerHolder.create(name, marshall, persistence); 96 | } 97 | 98 | private static Optional findAnnotation(Optional element, 99 | Class annotationType) { 100 | 101 | if (!element.isPresent()) { 102 | return Optional.empty(); 103 | } 104 | return element.flatMap(e -> findAnnotationForElement(annotationType, e)); 105 | } 106 | 107 | private static Optional findAnnotationForElement(final Class annotationType, 108 | final AnnotatedElement e) { 109 | return AnnotationUtils.findAnnotation(e, annotationType); 110 | } 111 | 112 | @Override 113 | public boolean supportsParameter(final ParameterContext parameterContext, 114 | final ExtensionContext extensionContext) { 115 | return parameterContext.isAnnotated(EmbeddedJms.class); 116 | } 117 | 118 | @Override 119 | public Object resolveParameter(final ParameterContext parameterContext, 120 | final ExtensionContext context) { 121 | final Parameter parameter = parameterContext.getParameter(); 122 | final EmbeddedJMSBrokerHolder embeddedJMSBrokerHolder = context.getStore(EMBEDDED_JMS_EXT) 123 | .get(STORE_EMBEDDED_JMS_BROKER, 124 | EmbeddedJMSBrokerHolder.class); 125 | if (ActiveMQConnectionFactory.class.isAssignableFrom(parameter.getType())) { 126 | return embeddedJMSBrokerHolder.getActiveMQConnectionFactory(); 127 | } else if (ConnectionFactory.class.isAssignableFrom(parameter.getType())) { 128 | return embeddedJMSBrokerHolder.getConnectionFactory(); 129 | } else if (URI.class.isAssignableFrom(parameter.getType())) { 130 | return embeddedJMSBrokerHolder.getBrokerUri(); 131 | } else { 132 | return null; 133 | } 134 | 135 | } 136 | 137 | @Override 138 | public void afterEach(final ExtensionContext context) { 139 | 140 | LOGGER.debug("afterEach \"{}\"", context.getTestClass()); 141 | Optional.ofNullable(context.getStore(EMBEDDED_JMS_EXT) 142 | .get(STORE_EMBEDDED_JMS_BROKER, EmbeddedJMSBrokerHolder.class)) 143 | .ifPresent(embeddedJMSBrokerHolder -> { 144 | try { 145 | embeddedJMSBrokerHolder.close(); 146 | } catch (Exception e) { 147 | throw new IllegalStateException("Could not close down Embedded broker", e); 148 | } 149 | }); 150 | } 151 | 152 | @Override 153 | public void beforeEach(final ExtensionContext context) { 154 | LOGGER.debug("beforeEach \"{}\"", context.getTestClass()); 155 | final BrokerConfiguration brokerConfigurationFromInstance = context.getStore(EMBEDDED_JMS_EXT).get( 156 | STORE_BROKER_CONFIGURATION, 157 | BrokerConfiguration.class); 158 | 159 | Optional.ofNullable(BrokerConfigurationBuilder.fromInstance(BrokerConfiguration.DEFAULT) 160 | .mergeWithBrokerConfiguration( 161 | brokerConfigurationFromInstance)) 162 | .map(brokerConfigurationBuilder -> { 163 | createBrokerConfigurationFromContext(context) 164 | .ifPresent(brokerConfigurationBuilder::mergeWithBrokerConfiguration); 165 | return brokerConfigurationBuilder; 166 | }) 167 | .map(BrokerConfigurationBuilder::build) 168 | .ifPresent(c -> context.getStore(EMBEDDED_JMS_EXT).put(STORE_BROKER_CONFIGURATION, c)); 169 | 170 | 171 | final EmbeddedJMSBrokerHolder embeddedJmsBrokerHolder = getOrCreateEmbeddedJMSBrokerHolder(context); 172 | embeddedJmsBrokerHolder.start(); 173 | 174 | Object testInstance = context.getStore(EMBEDDED_JMS_EXT).get(TEST_INSTANCE); 175 | if (testInstance == null) { 176 | testInstance = context.getTestInstance().orElse(null); 177 | } 178 | Optional.ofNullable(testInstance) 179 | .ifPresent(ti -> FieldInjector.injectToInstance(ti, embeddedJmsBrokerHolder)); 180 | } 181 | 182 | @Override 183 | public void postProcessTestInstance(final Object testInstance, final ExtensionContext context) { 184 | LOGGER.debug("postProcessTestInstance instance: \"{}\"", testInstance); 185 | context.getStore(EMBEDDED_JMS_EXT).put(TEST_INSTANCE, testInstance); 186 | 187 | createBrokerConfigurationFromContext(context) 188 | .ifPresent(c -> context.getStore(EMBEDDED_JMS_EXT).put(STORE_BROKER_CONFIGURATION, c)); 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.zapodot 8 | embedded-jms-parent 9 | 0.3-SNAPSHOT 10 | pom 11 | 12 | embedded-jms-core 13 | embedded-jms-junit 14 | embedded-jms-junit5 15 | 16 | Embedded JMS Testing utilities 17 | Library that provides JUnit extensions setting up an embedded JMS broker (ActiveMQ) for testing. 18 | For JUnit 4 it provides a @Rule, while for JUnit 5 Jupiter it provides an extension that may be enabled 19 | by either the @ExtendWith or @RegisterExtension annotations provided by Jupiter 20 | 21 | https://github.com/zapodot/embedded-jms-junit 22 | 23 | 24 | zapodot 25 | zapodot@gmail.com 26 | Sondre Eikanger Kvalø 27 | 28 | creator 29 | 30 | http://zapodot.org 31 | 32 | 33 | 34 | 35 | Apache License, Version 2.0 36 | http://www.apache.org/licenses/LICENSE-2.0 37 | repo 38 | 39 | 40 | 41 | scm:git:git@github.com:zapodot/embedded-jms-junit.git 42 | scm:git:git@github.com:zapodot/embedded-jms-junit.git 43 | https://github.com/zapodot/embedded-jms-junit 44 | 45 | 46 | 5.15.10 47 | 2.24.1 48 | 28.1-jre 49 | 1.8 50 | 1.2.0 51 | 2.3.1 52 | 4.12 53 | 5.5.1 54 | 1.3.1 55 | UTF-8 56 | 1.7.26 57 | 5.1.9.RELEASE 58 | 3.8.1 59 | 2.22.2 60 | 3.0.1 61 | 3.1.1 62 | 1.6.8 63 | 1.6 64 | 3.0.0-M2 65 | 4.3.0 66 | 2.7 67 | 2.22.0 68 | 0.8.5 69 | 70 | 71 | github 72 | https://github.com/zapodot/embedded-jms-junit/issues 73 | 74 | 75 | 76 | sonatype-nexus-snapshots 77 | https://oss.sonatype.org/content/repositories/snapshots 78 | 79 | 80 | sonatype-nexus-staging 81 | Nexus Release Repository 82 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | maven-enforcer-plugin 91 | ${maven-enforcer-plugin.version} 92 | 93 | 94 | 95 | 96 | ${java.version} 97 | 98 | 99 | 3.2.0 100 | 101 | 102 | 103 | 104 | 105 | 106 | maven-compiler-plugin 107 | ${maven-compiler-plugin.version} 108 | 109 | ${java.version} 110 | ${java.version} 111 | 112 | 113 | 114 | maven-surefire-plugin 115 | ${maven-surefire-plugin.version} 116 | 117 | 118 | org.jacoco 119 | jacoco-maven-plugin 120 | ${jacoco-maven-plugin.version} 121 | 122 | 123 | prepare-agent 124 | 125 | prepare-agent 126 | 127 | 128 | 129 | 130 | 131 | maven-source-plugin 132 | ${maven-source-plugin.version} 133 | 134 | 135 | attach-sources 136 | 137 | jar-no-fork 138 | 139 | 140 | 141 | 142 | 143 | maven-javadoc-plugin 144 | ${maven-javadoc-plugin.version} 145 | 146 | 147 | attach-javadocs 148 | 149 | jar 150 | 151 | 152 | 153 | 154 | Embedded JMS JUnit Rule API 155 | ${project.build.sourceEncoding} 156 | 157 | https://junit.org/junit4/javadoc/latest/ 158 | https://junit.org/junit5/docs/current/api/ 159 | https://docs.oracle.com/en/java/javase/11/docs/api/ 160 | https://activemq.apache.org/maven/apidocs/ 161 | 162 | en 163 | true 164 | zapodot at gmail dot com 165 |
Embedded JMS JUnit Rule API
166 |
This library and its documentation is made available under Apache Licence v.2.0
167 |
168 |
169 | 170 | org.eluder.coveralls 171 | coveralls-maven-plugin 172 | ${maven-coveralls-plugin.version} 173 | 174 | 175 | javax.xml.bind 176 | jaxb-api 177 | 2.3.1 178 | 179 | 180 | 181 | 182 | org.codehaus.mojo 183 | cobertura-maven-plugin 184 | ${maven-cobertura-plugin.version} 185 | 186 | xml 187 | 256m 188 | true 189 | 190 | 191 | 192 |
193 |
194 | 195 | 196 | maven-enforcer-plugin 197 | 198 | 199 | maven-compiler-plugin 200 | 201 | 202 | org.jacoco 203 | jacoco-maven-plugin 204 | 205 | 206 |
207 | 208 | 209 | release 210 | 211 | 212 | 213 | org.apache.maven.plugins 214 | maven-gpg-plugin 215 | ${maven-gpg-plugin.version} 216 | 217 | 218 | sign-artifacts 219 | verify 220 | 221 | sign 222 | 223 | 224 | 225 | 226 | 227 | org.sonatype.plugins 228 | nexus-staging-maven-plugin 229 | ${maven-nexus-staging-plugin.version} 230 | true 231 | 232 | sonatype-nexus-staging 233 | https://oss.sonatype.org/ 234 | true 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | org.zapodot 246 | embedded-jms-core 247 | ${project.version} 248 | 249 | 250 | org.slf4j 251 | slf4j-api 252 | ${slf4j.version} 253 | 254 | 255 | junit 256 | junit 257 | ${junit.version} 258 | 259 | 260 | org.junit.jupiter 261 | junit-jupiter-api 262 | ${junit-jupiter.version} 263 | 264 | 265 | org.junit.jupiter 266 | junit-jupiter-engine 267 | ${junit-jupiter.version} 268 | 269 | 270 | org.junit.vintage 271 | junit-vintage-engine 272 | ${junit-jupiter.version} 273 | 274 | 275 | org.junit.platform 276 | junit-platform-common 277 | ${junit-platform.version} 278 | 279 | 280 | org.apache.activemq 281 | activemq-broker 282 | ${activemq.version} 283 | 284 | 285 | org.apache.activemq 286 | activemq-kahadb-store 287 | ${activemq.version} 288 | 289 | 290 | com.google.guava 291 | guava 292 | ${guava.version} 293 | 294 | 295 | org.slf4j 296 | jcl-over-slf4j 297 | ${slf4j.version} 298 | test 299 | 300 | 301 | org.slf4j 302 | slf4j-simple 303 | ${slf4j.version} 304 | test 305 | 306 | 307 | org.springframework 308 | spring-jms 309 | ${spring.version} 310 | test 311 | 312 | 313 | commons-logging 314 | commons-logging 315 | 316 | 317 | 318 | 319 | org.apache.camel 320 | camel-test 321 | ${camel.version} 322 | test 323 | 324 | 325 | 326 | org.apache.activemq 327 | activemq-camel 328 | ${activemq.version} 329 | test 330 | 331 | 332 | commons-logging 333 | commons-logging 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 |
--------------------------------------------------------------------------------