├── .github └── workflows │ └── build.yml ├── .gitignore ├── LICENSE ├── NOTICE ├── README.md ├── packaged-pooled-jms ├── pom.xml └── src │ └── main │ └── assembly │ ├── LICENSE │ ├── NOTICE │ ├── README.txt │ ├── bin.xml │ ├── licenses │ ├── jakarta.jms-api.EPL-2.0.txt │ └── slf4j-MIT.txt │ └── src.xml ├── pom.xml ├── pooled-jms-docs ├── Configuration.md ├── README.txt └── pom.xml ├── pooled-jms-examples ├── README.txt ├── pom.xml └── src │ └── main │ ├── java │ └── org │ │ └── messaginghub │ │ └── jms │ │ └── example │ │ └── HelloWorld.java │ └── resources │ ├── jndi.properties │ └── simplelogger.properties ├── pooled-jms-interop-tests ├── README.md ├── pom.xml ├── pooled-jms-artemis-tests │ ├── pom.xml │ └── src │ │ └── test │ │ ├── java │ │ └── org │ │ │ └── messaginghub │ │ │ └── pooled │ │ │ └── jms │ │ │ ├── ArtemisJmsPoolTestSupport.java │ │ │ ├── PooledConnectionFactoryTest.java │ │ │ └── PooledConnectionTest.java │ │ └── resources │ │ └── simplelogger.properties └── pooled-jms-qpid-jms-tests │ ├── .gitignore │ ├── pom.xml │ └── src │ └── test │ ├── java │ └── org │ │ └── messaginghub │ │ └── pooled │ │ └── jms │ │ ├── PooledConnectionFactoryTest.java │ │ ├── PooledConnectionTest.java │ │ ├── QpidJmsPoolTestSupport.java │ │ └── util │ │ └── Wait.java │ └── resources │ └── simplelogger.properties └── pooled-jms ├── pom.xml └── src ├── main └── java │ └── org │ └── messaginghub │ └── pooled │ └── jms │ ├── JmsPoolConnection.java │ ├── JmsPoolConnectionFactory.java │ ├── JmsPoolJMSConsumer.java │ ├── JmsPoolJMSContext.java │ ├── JmsPoolJMSProducer.java │ ├── JmsPoolJcaConnectionFactory.java │ ├── JmsPoolMessageConsumer.java │ ├── JmsPoolMessageProducer.java │ ├── JmsPoolQueueBrowser.java │ ├── JmsPoolQueueReceiver.java │ ├── JmsPoolQueueSender.java │ ├── JmsPoolSession.java │ ├── JmsPoolSessionEventListener.java │ ├── JmsPoolTopicPublisher.java │ ├── JmsPoolTopicSubscriber.java │ ├── JmsPoolXAConnectionFactory.java │ ├── JmsPoolXAJMSContext.java │ ├── package.html │ ├── pool │ ├── PooledConnection.java │ ├── PooledConnectionKey.java │ ├── PooledJCAConnection.java │ ├── PooledSessionHolder.java │ ├── PooledSessionKey.java │ └── PooledXAConnection.java │ └── util │ ├── IntrospectionSupport.java │ ├── JMSExceptionSupport.java │ ├── JMSMessagePropertySupport.java │ ├── LRUCache.java │ └── TypeConversionSupport.java ├── site └── findbugs-exclude.xml └── test ├── java └── org │ └── messaginghub │ └── pooled │ └── jms │ ├── JmsPoolConnectionFactoryMaximumActiveTest.java │ ├── JmsPoolConnectionFactoryTest.java │ ├── JmsPoolConnectionIdleEvictionsFromPoolTest.java │ ├── JmsPoolConnectionSecurityExceptionTest.java │ ├── JmsPoolConnectionTemporaryDestinationTest.java │ ├── JmsPoolConnectionTest.java │ ├── JmsPoolJMSConsumerTest.java │ ├── JmsPoolJMSContextTest.java │ ├── JmsPoolJMSProducerTest.java │ ├── JmsPoolMessageConsumerTest.java │ ├── JmsPoolMessageProducerTest.java │ ├── JmsPoolQueueReceiverTest.java │ ├── JmsPoolQueueSenderTest.java │ ├── JmsPoolReconnectOnFailureTest.java │ ├── JmsPoolSessionExhaustionTest.java │ ├── JmsPoolSessionTest.java │ ├── JmsPoolTestSupport.java │ ├── JmsPoolTopicPublisherTest.java │ ├── JmsPoolTopicSubscriberTest.java │ ├── JmsPoolWrappedProducersTest.java │ ├── JmsPoolXAConnectionTest.java │ ├── JmsQueueBrowserTest.java │ ├── mock │ ├── MockJMSBytesMessage.java │ ├── MockJMSConnection.java │ ├── MockJMSConnectionFactory.java │ ├── MockJMSConnectionListener.java │ ├── MockJMSConnectionMetaData.java │ ├── MockJMSConnectionStats.java │ ├── MockJMSConsumer.java │ ├── MockJMSContext.java │ ├── MockJMSDefaultConnectionListener.java │ ├── MockJMSDefaultSessionListener.java │ ├── MockJMSDestination.java │ ├── MockJMSMapMessage.java │ ├── MockJMSMessage.java │ ├── MockJMSMessageConsumer.java │ ├── MockJMSMessageProducer.java │ ├── MockJMSObjectMessage.java │ ├── MockJMSProducer.java │ ├── MockJMSQueue.java │ ├── MockJMSQueueBrowser.java │ ├── MockJMSQueueReceiver.java │ ├── MockJMSQueueSender.java │ ├── MockJMSQueueSession.java │ ├── MockJMSSession.java │ ├── MockJMSSessionListener.java │ ├── MockJMSStreamMessage.java │ ├── MockJMSTemporaryDestination.java │ ├── MockJMSTemporaryQueue.java │ ├── MockJMSTemporaryTopic.java │ ├── MockJMSTextMessage.java │ ├── MockJMSTopic.java │ ├── MockJMSTopicPublisher.java │ ├── MockJMSTopicSession.java │ ├── MockJMSTopicSubscriber.java │ ├── MockJMSUser.java │ ├── MockJMSXAConnection.java │ ├── MockJMSXAConnectionFactory.java │ └── MockJMSXASession.java │ └── util │ ├── JMSExceptionSupportTest.java │ ├── JMSMessagePropertySupportTest.java │ ├── SocketProxy.java │ ├── TypeConversionSupportTest.java │ └── Wait.java └── resources └── simplelogger.properties /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: "Build" 2 | 3 | on: [push, pull_request, workflow_dispatch] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | fail-fast: false 10 | matrix: 11 | java: [ 11, 17, 21 ] 12 | 13 | steps: 14 | - uses: actions/checkout@v3 15 | - uses: actions/cache@v3 16 | with: 17 | path: ~/.m2/repository 18 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 19 | restore-keys: | 20 | ${{ runner.os }}-maven- 21 | - name: Install JDK ${{ matrix.java }} 22 | uses: actions/setup-java@v3 23 | with: 24 | java-version: ${{ matrix.java }} 25 | distribution: 'temurin' 26 | 27 | - name: Build & Test 28 | run: mvn clean verify 29 | 30 | - name: Javadoc etc 31 | run: mvn clean verify -Prelease -Dgpg.skip -DskipTests 32 | 33 | - name: RAT check 34 | run: mvn clean -Prelease apache-rat:check 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Log file 2 | *.log 3 | 4 | # BlueJ files 5 | *.ctxt 6 | 7 | # Mobile Tools for Java (J2ME) 8 | .mtj.tmp/ 9 | 10 | # Package Files # 11 | *.jar 12 | *.war 13 | *.ear 14 | *.zip 15 | *.tar.gz 16 | *.rar 17 | 18 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 19 | hs_err_pid* 20 | 21 | *~ 22 | *.swp 23 | 24 | # Start of IntelliJ IDE files 25 | .idea 26 | .idea/* 27 | *.iml 28 | *.ipr 29 | *.iws 30 | # End of IntelliJ IDE files 31 | 32 | /build/ 33 | *.class 34 | *.pyc 35 | *.pyo 36 | target 37 | release.properties 38 | 39 | .DS_Store 40 | 41 | # Start of Eclipse IDE files 42 | .project 43 | .classpath 44 | .settings 45 | .cproject 46 | eclipse-classes 47 | # End of Eclipse IDE files 48 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Pooled JMS 2 | Copyright [2017-2024] The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PooledJMS 2 | 3 | JMS Connection pool for messaging applications that provides pooling for JMS Connections, Sessions and MessageProducers. 4 | 5 | This project was forked from the ActiveMQ JMS Pool and enhanced to provide JMS 2.0 functionality. 6 | 7 | Following the 3.0 release this project has transitioned to the Jakarta JMS API. For those still using JMS 2.0 or 1.1 based clients the previous 2.x release series should be used. 8 | 9 | Below are some quick pointers you might find useful. 10 | 11 | ## Using the PooledJMS library 12 | 13 | To use the PooledJMS library in your projects you can include the maven 14 | dependency in your project pom file: 15 | 16 | 17 | org.messaginghub 18 | pooled-jms 19 | ${pooled-jms-version} 20 | 21 | 22 | ## Building the code 23 | 24 | The project requires Maven 3. Some example commands follow. 25 | 26 | Clean previous builds output and install all modules to local repository without 27 | running the tests: 28 | 29 | mvn clean install -DskipTests 30 | 31 | Install all modules to the local repository after running all the tests: 32 | 33 | mvn clean install 34 | 35 | Perform a subset tests on the packaged release artifacts without 36 | installing: 37 | 38 | mvn clean verify -Dtest=TestNamePattern* 39 | 40 | Execute the tests and produce code coverage report: 41 | 42 | mvn clean test jacoco:report 43 | 44 | ## Examples 45 | 46 | First build and install all the modules as detailed above (if running against 47 | a source checkout/release, rather than against released binaries) and then 48 | consult the README in the pooled-jms-examples module itself. 49 | 50 | ## Documentation 51 | 52 | There is some basic documentation in the pooled-jms-docs module. 53 | 54 | ## Continuous Integration 55 | 56 | [![Build](https://github.com/messaginghub/pooled-jms/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/messaginghub/pooled-jms/actions/workflows/build.yml) 57 | -------------------------------------------------------------------------------- /packaged-pooled-jms/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 4.0.0 20 | 21 | org.messaginghub 22 | pooled-jms-parent 23 | 3.1.8-SNAPSHOT 24 | 25 | 26 | packaged-pooled-jms 27 | pom 28 | Packaged Pooled-JMS 29 | 30 | 31 | 32 | org.messaginghub 33 | pooled-jms 34 | 35 | 36 | 37 | 38 | true 39 | 40 | 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-deploy-plugin 46 | 47 | true 48 | 49 | 50 | 51 | org.apache.maven.plugins 52 | maven-assembly-plugin 53 | 54 | 55 | make-assembly 56 | package 57 | 58 | single 59 | 60 | 61 | 62 | src/main/assembly/bin.xml 63 | src/main/assembly/src.xml 64 | 65 | posix 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /packaged-pooled-jms/src/main/assembly/NOTICE: -------------------------------------------------------------------------------- 1 | Pooled JMS 2 | Copyright [2017-2024] The Apache Software Foundation 3 | 4 | This product includes software developed at 5 | The Apache Software Foundation (http://www.apache.org/). 6 | -------------------------------------------------------------------------------- /packaged-pooled-jms/src/main/assembly/README.txt: -------------------------------------------------------------------------------- 1 | Pooled-JMS 2 | 3 | For a basic overview of the Pooled-JMS project see the docs directory. 4 | 5 | For examples of using the JMS Pool, see the examples directory. 6 | 7 | The JMS pool artifacts and required dependencies can be found 8 | in the lib directory. 9 | -------------------------------------------------------------------------------- /packaged-pooled-jms/src/main/assembly/bin.xml: -------------------------------------------------------------------------------- 1 | 2 | 22 | 25 | bin 26 | 27 | tar.gz 28 | 29 | packaged-pooled-jms-${project.version} 30 | 31 | 32 | ${basedir}/src/main/assembly/ 33 | / 34 | 35 | README.txt 36 | LICENSE 37 | NOTICE 38 | licenses/* 39 | 40 | 0644 41 | 0755 42 | 43 | 44 | 45 | 46 | /lib 47 | false 48 | true 49 | 50 | 51 | 52 | 53 | true 54 | 55 | org.messaginghub:pooled-jms-examples 56 | 57 | 58 | false 59 | 60 | 61 | src 62 | examples/src 63 | 0644 64 | 0755 65 | 66 | 67 | examples/ 68 | 69 | pom.xml 70 | README.txt 71 | 72 | 0644 73 | 0755 74 | 75 | 76 | 77 | 78 | 79 | true 80 | 81 | org.messaginghub:pooled-jms-docs 82 | 83 | 84 | false 85 | 86 | 87 | 88 | *.md 89 | README.txt 90 | 91 | docs 92 | 0644 93 | 0755 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /packaged-pooled-jms/src/main/assembly/licenses/slf4j-MIT.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2022 QOS.ch Sarl (Switzerland) 2 | All rights reserved. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /packaged-pooled-jms/src/main/assembly/src.xml: -------------------------------------------------------------------------------- 1 | 2 | 20 | 21 | 22 | src 23 | 24 | tar.gz 25 | 26 | packaged-pooled-jms-${project.version}-src 27 | 28 | 29 | 30 | ${project.basedir}/.. 31 | / 32 | true 33 | 34 | 35 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/).*${project.build.directory}.*] 36 | 37 | 48 | 49 | 50 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?maven-eclipse\.xml] 51 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.project] 52 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.classpath] 53 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.iws] 54 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.idea(/.*)?] 55 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?out(/.*)?] 56 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.ipr] 57 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?[^/]*\.iml] 58 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.settings(/.*)?] 59 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.externalToolBuilders(/.*)?] 60 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.deployables(/.*)?] 61 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.wtpmodules(/.*)?] 62 | 63 | 64 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?cobertura\.ser] 65 | 66 | 67 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?pom\.xml\.releaseBackup] 68 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?release\.properties] 69 | 70 | 71 | %regex[(?!((?!${project.build.directory}/)[^/]+/)*src/)(.*/)?\.repository(/.*)?] 72 | 73 | 74 | 75 | ${project.build.directory}/maven-shared-archive-resources/META-INF 76 | / 77 | 78 | 79 | DEPENDENCIES 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /pooled-jms-docs/Configuration.md: -------------------------------------------------------------------------------- 1 | # JMS Pool configuration 2 | 3 | This file details various configuration options for the JMS Pool, such as how to control the number of connection stored in the pool etc. 4 | 5 | ## Creating a Pooling ConnectionFactory 6 | 7 | The JMS Pool operates as a standard JMS ConnectionFactory instance that wraps the ConnectionFactory of your chosen JMS Provider and manages the lifetime of Connections from that provider based on the configuration of the JMS Pool. The JMS Pool can be configured to share a single JMS Connection or a number of Connections amongst callers to the Pool's createConnection methods. 8 | 9 | ## Configuration Options 10 | 11 | The JMS Pool's ConnectionFactory implementation exposes a number of configuration options that control the behavior of the pool and the JMS resources it manages. There are settings that control how many Connections are created in the pool and how long those Connections can remain idle etc. There are also settings that control how many Sessions a loaned Connection from the pool is allowed to create and how the pooled Connection behaves when it cannot create any new Sessions for a given loaned Connection. 12 | 13 | ### Connection Related Options 14 | 15 | These options affect how the JMS pool creates and manages the Connections in the pool. 16 | 17 | + **maxConnections** Determines the maximum number of Connections the the pool maintains in a single Connection pool (defaults to one). The pooled ConnectionFactory manages a pool of connection per each unique user + password combination value used to create connection, plus a separate pool for anonymous Connections (those without user-name or password). 18 | + **connectionIdleTimeout** The idle timeout (default 30 seconds) controls how long a Connection that hasn't been or currently isn't loaned out to any client will remain idle in the Connection pool before it is eligible to be closed and discarded. To disable idle timeouts the value should be set to 0 or a negative number. 19 | + **connectionCheckInterval** used to establish a periodic check for expired Connections which will close all Connection that have exceeded the set expiration value. This value is set to 0ms by default and only activates if set to a positive non-zero value. 20 | + **useProviderJMSContext** by default the JMS pool will use it's own generic JMSContext classes to wrap a Connection borrowed from the pool instead of using the JMSContext functionality of the JMS ConnectionFactory that was configured. This generic JMSContext implementation may be limited compared to the Provider version and if that functionality is critical to the application this option can be enabled to force the pool to use the Provider JMSContext implementation. When enabled the JMSContext API is then not part of the Connections that are pooled by this JMS Connection pooling library. 21 | 22 | ## Session Related Options 23 | 24 | These options affect the behavior of Sessions that are created from the pooled Connections. 25 | 26 | + **maxSessionsPerConnection** For each Connection in the pool there can be a configured maximum number of Sessions that the pooled Connection will loan out before either blocking or throwing an error (based on configuration). By default this value is 500 meaning that each provider Connection is limited to 500 sessions, this limit can be disabled by setting the value to a negative number. 27 | + **blockIfSessionPoolIsFull** When true (default) a call to createSession on a Connection from the pool will block until another previously created and loaned out session is closed an thereby becomes available. When false a call to createSession when no Session is available will throw an IllegalStateException to indicate that the Connection is not able to provide a new Session at that time. 28 | + **blockIfSessionPoolIsFullTimeout** When the blockIfSessionPoolIsFull option is enabled and this value is set then a call to createSession that has blocked awaiting a Session will wait for the specified number of milliseconds before throwing an IllegalStateException. By default this value is set to -1 indicating that the createSession call should block forever if configured to wait. 29 | + **useAnonymousProducers** By default a Session that has been loaned out on a call to createSession will use a single anonymous JMS MessageProducer as the underlying producer for all calls to createProducer. In some rare cases this is not desirable and this feature can be disabled using this option, when disabled every call to createProducer will result in a new MessageProducer instance being created. 30 | -------------------------------------------------------------------------------- /pooled-jms-docs/README.txt: -------------------------------------------------------------------------------- 1 | The docs are raw Markdown right now, we still need to put stuff in place to convert 2 | to other formats like HTML. 3 | 4 | Until then you might find it easier to view them by browsing the GitHub repository: 5 | https://github.com/messaginghub/pooled-jms 6 | -------------------------------------------------------------------------------- /pooled-jms-docs/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | org.messaginghub 20 | pooled-jms-parent 21 | 3.1.8-SNAPSHOT 22 | 23 | 4.0.0 24 | 25 | pooled-jms-docs 26 | pom 27 | PooledJMS Documentation 28 | 29 | 30 | true 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-deploy-plugin 38 | 39 | true 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /pooled-jms-examples/README.txt: -------------------------------------------------------------------------------- 1 | =========================== 2 | Running the pool examples 3 | =========================== 4 | 5 | Use maven to build the module, and additionally copy the dependencies 6 | alongside their output: 7 | 8 | mvn clean package dependency:copy-dependencies -DincludeScope=runtime -DskipTests 9 | 10 | Now you can run the examples using commands of the format: 11 | 12 | Linux: java -cp "target/classes/:target/dependency/*" org.messaginghub.jms.example.HelloWorld 13 | 14 | Windows: java -cp "target\classes\;target\dependency\*" org.messaginghub.jms.example.HelloWorld 15 | 16 | NOTE: The examples expect to use a Queue named "queue". You may need to create 17 | this before running the examples, depending on the broker/peer you are using. 18 | 19 | NOTE: By default the examples can only connect anonymously. A username and 20 | password with which the connection can authenticate with the server may be set 21 | through system properties named USER and PASSWORD respectively. E.g: 22 | 23 | Linux: java -DUSER=guest -DPASSWORD=guest -cp "target/classes/:target/dependency/*" org.messaginghub.jms.example.HelloWorld 24 | 25 | Windows: java -DUSER=guest -DPASSWORD=guest -cp "target\classes\;target\dependency\*" org.messaginghub.jms.example.HelloWorld 26 | 27 | NOTE: You can configure the connection and queue details used by updating the 28 | JNDI configuration file before building. It can be found at: 29 | src/main/resources/jndi.properties 30 | 31 | NOTE: The earlier build command will cause Maven to resolve the client artifact 32 | dependencies against its local and remote repositories. If you wish to use a 33 | locally-built client, ensure to "mvn install" it in your local repo first. 34 | -------------------------------------------------------------------------------- /pooled-jms-examples/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 4.0.0 20 | 21 | org.messaginghub 22 | pooled-jms-parent 23 | 3.1.8-SNAPSHOT 24 | 25 | 26 | pooled-jms-examples 27 | PooledJMS Examples 28 | Examples showing the use of the JMS Pool 29 | jar 30 | 31 | 32 | true 33 | 34 | 35 | 36 | 37 | org.messaginghub 38 | pooled-jms 39 | 40 | 41 | org.apache.qpid 42 | qpid-jms-client 43 | runtime 44 | 45 | 46 | 48 | 49 | org.slf4j 50 | slf4j-simple 51 | 52 | 53 | 54 | 55 | 56 | 57 | org.apache.maven.plugins 58 | maven-deploy-plugin 59 | 60 | 62 | true 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /pooled-jms-examples/src/main/java/org/messaginghub/jms/example/HelloWorld.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Licensed to the Apache Software Foundation (ASF) under one 4 | * or more contributor license agreements. See the NOTICE file 5 | * distributed with this work for additional information 6 | * regarding copyright ownership. The ASF licenses this file 7 | * to you under the Apache License, Version 2.0 (the 8 | * "License"); you may not use this file except in compliance 9 | * with the License. You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, 14 | * software distributed under the License is distributed on an 15 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | * KIND, either express or implied. See the License for the 17 | * specific language governing permissions and limitations 18 | * under the License. 19 | * 20 | */ 21 | package org.messaginghub.jms.example; 22 | 23 | import jakarta.jms.Connection; 24 | import jakarta.jms.ConnectionFactory; 25 | import jakarta.jms.DeliveryMode; 26 | import jakarta.jms.Destination; 27 | import jakarta.jms.ExceptionListener; 28 | import jakarta.jms.JMSException; 29 | import jakarta.jms.Message; 30 | import jakarta.jms.MessageConsumer; 31 | import jakarta.jms.MessageProducer; 32 | import jakarta.jms.Session; 33 | import jakarta.jms.TextMessage; 34 | import javax.naming.Context; 35 | import javax.naming.InitialContext; 36 | 37 | import org.messaginghub.pooled.jms.JmsPoolConnectionFactory; 38 | 39 | public class HelloWorld { 40 | 41 | public static void main(String[] args) throws Exception { 42 | JmsPoolConnectionFactory poolingFactory = new JmsPoolConnectionFactory(); 43 | 44 | try { 45 | // The configuration for the Qpid InitialContextFactory has been supplied in 46 | // a jndi.properties file in the classpath, which results in it being picked 47 | // up automatically by the InitialContext constructor. 48 | Context context = new InitialContext(); 49 | 50 | ConnectionFactory factory = (ConnectionFactory) context.lookup("myFactoryLookup"); 51 | 52 | poolingFactory.setConnectionFactory(factory); 53 | 54 | Destination queue = (Destination) context.lookup("myQueueLookup"); 55 | 56 | final String messagePayload = "Hello World"; 57 | 58 | // Each send should end up reusing the same Connection and Session from the pool 59 | for (int i = 0; i < messagePayload.length(); ++i) { 60 | Connection connection = poolingFactory.createConnection(System.getProperty("USER"), System.getProperty("PASSWORD")); 61 | connection.setExceptionListener(new MyExceptionListener()); 62 | 63 | Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 64 | 65 | MessageProducer messageProducer = session.createProducer(queue); 66 | 67 | TextMessage message = session.createTextMessage("" + messagePayload.charAt(i)); 68 | messageProducer.send(message, DeliveryMode.NON_PERSISTENT, Message.DEFAULT_PRIORITY, Message.DEFAULT_TIME_TO_LIVE); 69 | 70 | connection.close(); 71 | } 72 | 73 | // The consumer should reuse the same Connection as the senders, broker should register only 74 | // one connection having been used for this full example. 75 | Connection connection = poolingFactory.createConnection(System.getProperty("USER"), System.getProperty("PASSWORD")); 76 | connection.setExceptionListener(new MyExceptionListener()); 77 | connection.start(); 78 | 79 | Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 80 | 81 | StringBuilder messageReceived = new StringBuilder().append("Received: "); 82 | 83 | MessageConsumer messageConsumer = session.createConsumer(queue); 84 | for (int i = 0; i < messagePayload.length(); ++i) { 85 | TextMessage receivedMessage = (TextMessage) messageConsumer.receive(2000l); 86 | if (receivedMessage != null) { 87 | messageReceived.append(receivedMessage.getText()); 88 | } else { 89 | messageReceived.setLength(0); 90 | messageReceived.append("No message received within the given timeout!"); 91 | System.out.println("No message received within the given timeout!"); 92 | break; 93 | } 94 | } 95 | 96 | System.out.println(messageReceived.toString()); 97 | 98 | connection.close(); 99 | } catch (Exception exp) { 100 | System.out.println("Caught exception, exiting."); 101 | exp.printStackTrace(System.out); 102 | System.exit(1); 103 | } finally { 104 | poolingFactory.stop(); 105 | } 106 | } 107 | 108 | private static class MyExceptionListener implements ExceptionListener { 109 | @Override 110 | public void onException(JMSException exception) { 111 | System.out.println("Connection ExceptionListener fired, exiting."); 112 | exception.printStackTrace(System.out); 113 | System.exit(1); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /pooled-jms-examples/src/main/resources/jndi.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | 20 | # Set the InitialContextFactory class to use 21 | java.naming.factory.initial = org.apache.qpid.jms.jndi.JmsInitialContextFactory 22 | 23 | # Define the required ConnectionFactory instances 24 | # connectionfactory. = 25 | connectionfactory.myFactoryLookup = amqp://localhost:5672 26 | 27 | # Configure the necessary Queue and Topic objects 28 | # queue. = 29 | # topic. = 30 | queue.myQueueLookup = queue 31 | topic.myTopicLookup = topic -------------------------------------------------------------------------------- /pooled-jms-examples/src/main/resources/simplelogger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | org.slf4j.simpleLogger.logFile=System.out 20 | 21 | org.slf4j.simpleLogger.defaultLogLevel=debug 22 | 23 | org.slf4j.simpleLogger.showDateTime=true 24 | org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss,SSS 25 | 26 | org.slf4j.simpleLogger.log.org.messaginghub.pooled.jms=DEBUG 27 | 28 | -------------------------------------------------------------------------------- /pooled-jms-interop-tests/README.md: -------------------------------------------------------------------------------- 1 | JMS Pool Client Interop tests 2 | ---------------------------------------------- 3 | This module contains maven submodules that should exercise the JMS Pool using various JMS client implementations. 4 | -------------------------------------------------------------------------------- /pooled-jms-interop-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 4.0.0 19 | 20 | org.messaginghub 21 | pooled-jms-parent 22 | 3.1.8-SNAPSHOT 23 | 24 | 25 | pooled-jms-interop-tests 26 | PooledJMS Client Interop Tests 27 | A set of modules meant for testing interoperability between the JMS Pool and various JMS client implementations. 28 | pom 29 | 30 | UTF-8 31 | true 32 | 33 | 34 | 35 | pooled-jms-qpid-jms-tests 36 | pooled-jms-artemis-tests 37 | 38 | 39 | 40 | 41 | 42 | org.apache.maven.plugins 43 | maven-deploy-plugin 44 | 45 | true 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /pooled-jms-interop-tests/pooled-jms-artemis-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 4.0.0 20 | 21 | org.messaginghub 22 | pooled-jms-interop-tests 23 | 3.1.8-SNAPSHOT 24 | 25 | 26 | pooled-jms-artemis-tests 27 | PooledJMS ActiveMQ Artemis JMS Client Interop Tests 28 | Tests the JMS Pool using the client from the ActiveMQ Artemis client and broker. 29 | jar 30 | 31 | UTF-8 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | jakarta.jms 41 | jakarta.jms-api 42 | 43 | 44 | org.messaginghub 45 | pooled-jms 46 | 47 | 48 | org.slf4j 49 | slf4j-api 50 | 51 | 52 | 53 | 54 | 55 | 56 | org.junit.jupiter 57 | junit-jupiter-api 58 | test 59 | 60 | 61 | org.junit.jupiter 62 | junit-jupiter-engine 63 | test 64 | 65 | 66 | org.junit.jupiter 67 | junit-jupiter-params 68 | test 69 | 70 | 71 | org.slf4j 72 | slf4j-simple 73 | test 74 | 75 | 76 | org.apache.activemq 77 | artemis-server 78 | test 79 | 80 | 81 | org.apache.activemq 82 | artemis-jakarta-client 83 | test 84 | 85 | 86 | 87 | 88 | 89 | 90 | org.apache.maven.plugins 91 | maven-deploy-plugin 92 | 93 | true 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /pooled-jms-interop-tests/pooled-jms-artemis-tests/src/test/java/org/messaginghub/pooled/jms/ArtemisJmsPoolTestSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import java.util.Map; 20 | 21 | import org.apache.activemq.artemis.api.core.SimpleString; 22 | import org.apache.activemq.artemis.api.core.TransportConfiguration; 23 | import org.apache.activemq.artemis.core.config.Configuration; 24 | import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl; 25 | import org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory; 26 | import org.apache.activemq.artemis.core.remoting.impl.invm.TransportConstants; 27 | import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ; 28 | import org.apache.activemq.artemis.core.settings.impl.AddressSettings; 29 | import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; 30 | import org.junit.jupiter.api.AfterEach; 31 | import org.junit.jupiter.api.BeforeEach; 32 | import org.junit.jupiter.api.TestInfo; 33 | import org.slf4j.Logger; 34 | import org.slf4j.LoggerFactory; 35 | 36 | public class ArtemisJmsPoolTestSupport { 37 | 38 | protected static final Logger LOG = LoggerFactory.getLogger(ArtemisJmsPoolTestSupport.class); 39 | 40 | private static final String SERVER_NAME = "embedded-server"; 41 | 42 | protected String testName; 43 | protected ActiveMQConnectionFactory artemisJmsConnectionFactory; 44 | protected JmsPoolConnectionFactory cf; 45 | 46 | protected Configuration configuration; 47 | protected EmbeddedActiveMQ server; 48 | 49 | @BeforeEach 50 | public void setUp(TestInfo info) throws Exception { 51 | LOG.info("========== started test: " + info.getDisplayName() + " =========="); 52 | 53 | testName = info.getDisplayName(); 54 | 55 | configuration = new ConfigurationImpl().setName(SERVER_NAME) 56 | .setPersistenceEnabled(false) 57 | .setSecurityEnabled(false) 58 | .addAcceptorConfiguration(new TransportConfiguration(InVMAcceptorFactory.class.getName())) 59 | .addAddressesSetting("#", new AddressSettings().setDeadLetterAddress(SimpleString.of("dla")).setExpiryAddress(SimpleString.of("expiry"))); 60 | server = new EmbeddedActiveMQ().setConfiguration(configuration); 61 | server.start(); 62 | 63 | artemisJmsConnectionFactory = new ActiveMQConnectionFactory(getVmURL()); 64 | 65 | cf = new JmsPoolConnectionFactory(); 66 | cf.setConnectionFactory(artemisJmsConnectionFactory); 67 | cf.setMaxConnections(1); 68 | } 69 | 70 | private String getVmURL() { 71 | String vmURL = "vm://0"; 72 | for (TransportConfiguration transportConfiguration : configuration.getAcceptorConfigurations()) { 73 | Map params = transportConfiguration.getParams(); 74 | if (params != null && params.containsKey(TransportConstants.SERVER_ID_PROP_NAME)) { 75 | vmURL = "vm://" + params.get(TransportConstants.SERVER_ID_PROP_NAME); 76 | } 77 | } 78 | 79 | return vmURL; 80 | } 81 | 82 | @AfterEach 83 | public void tearDown() throws Exception { 84 | if (cf != null) { 85 | cf.stop(); 86 | } 87 | 88 | server.stop(); 89 | 90 | LOG.info("========== completed test: " + getTestName() + " =========="); 91 | } 92 | 93 | public String getTestName() { 94 | return testName; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /pooled-jms-interop-tests/pooled-jms-artemis-tests/src/test/java/org/messaginghub/pooled/jms/PooledConnectionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertEquals; 20 | import static org.junit.jupiter.api.Assertions.fail; 21 | 22 | import jakarta.jms.Connection; 23 | import jakarta.jms.IllegalStateException; 24 | import jakarta.jms.Session; 25 | import jakarta.jms.Topic; 26 | import jakarta.jms.TopicConnection; 27 | import jakarta.jms.TopicPublisher; 28 | import jakarta.jms.TopicSession; 29 | 30 | import org.junit.jupiter.api.Test; 31 | import org.junit.jupiter.api.Timeout; 32 | import org.slf4j.Logger; 33 | import org.slf4j.LoggerFactory; 34 | 35 | /** 36 | * A test against the PooledConnection class using QpidJMS 37 | */ 38 | @Timeout(60) 39 | public class PooledConnectionTest extends ArtemisJmsPoolTestSupport { 40 | 41 | private final Logger LOG = LoggerFactory.getLogger(PooledConnectionTest.class); 42 | 43 | @Test 44 | public void testSetClientIDTwiceWithSameID() throws Exception { 45 | // test: call setClientID("newID") twice 46 | // this should be tolerated and not result in an exception 47 | Connection connection = cf.createConnection(); 48 | connection.setClientID("newID"); 49 | 50 | try { 51 | connection.setClientID("newID"); 52 | connection.start(); 53 | connection.close(); 54 | } catch (IllegalStateException ise) { 55 | LOG.error("Repeated calls to newID2.setClientID(\"newID\") caused " + ise.getMessage()); 56 | fail("Repeated calls to newID2.setClientID(\"newID\") caused " + ise.getMessage()); 57 | } finally { 58 | cf.stop(); 59 | } 60 | 61 | LOG.debug("Test finished."); 62 | } 63 | 64 | @Test 65 | public void testSetClientIDTwiceWithDifferentID() throws Exception { 66 | Connection connection = cf.createConnection(); 67 | 68 | // test: call setClientID() twice with different IDs 69 | // this should result in an IllegalStateException 70 | connection.setClientID("newID1"); 71 | try { 72 | connection.setClientID("newID2"); 73 | fail("calling Connection.setClientID() twice with different clientID must raise an IllegalStateException"); 74 | } catch (IllegalStateException ise) { 75 | LOG.debug("Correctly received " + ise); 76 | } finally { 77 | connection.close(); 78 | cf.stop(); 79 | } 80 | 81 | LOG.debug("Test finished."); 82 | } 83 | 84 | @Test 85 | public void testSetClientIDAfterConnectionStart() throws Exception { 86 | Connection connection = cf.createConnection(); 87 | 88 | // test: try to call setClientID() after start() 89 | // should result in an exception 90 | try { 91 | connection.start(); 92 | connection.setClientID("newID3"); 93 | fail("Calling setClientID() after start() mut raise a JMSException."); 94 | } catch (IllegalStateException ise) { 95 | LOG.debug("Correctly received " + ise); 96 | } finally { 97 | connection.close(); 98 | cf.stop(); 99 | } 100 | 101 | LOG.debug("Test finished."); 102 | } 103 | 104 | @Test 105 | public void testTopicMessageSend() throws Exception { 106 | cf.setMaxConnections(1); 107 | 108 | TopicConnection connection = cf.createTopicConnection(); 109 | 110 | try { 111 | TopicSession topicSession = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); 112 | Topic topic = topicSession.createTopic(getTestName()); 113 | 114 | TopicPublisher topicPublisher = topicSession.createPublisher(topic); 115 | topicPublisher.send(topicSession.createMessage()); 116 | assertEquals(1, cf.getNumConnections()); 117 | } finally { 118 | connection.close(); 119 | cf.stop(); 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /pooled-jms-interop-tests/pooled-jms-artemis-tests/src/test/resources/simplelogger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | org.slf4j.simpleLogger.logFile=System.out 20 | 21 | org.slf4j.simpleLogger.defaultLogLevel=trace 22 | 23 | org.slf4j.simpleLogger.showDateTime=true 24 | org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss,SSS 25 | 26 | org.slf4j.simpleLogger.log.org.messaginghub.pooled.jms=DEBUG 27 | 28 | -------------------------------------------------------------------------------- /pooled-jms-interop-tests/pooled-jms-qpid-jms-tests/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /pooled-jms-interop-tests/pooled-jms-qpid-jms-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 4.0.0 20 | 21 | org.messaginghub 22 | pooled-jms-interop-tests 23 | 3.1.8-SNAPSHOT 24 | 25 | 26 | pooled-jms-qpid-jms-tests 27 | PooledJMS Qpid JMS Client Interop Tests 28 | Tests the JMS Pool using the Qpid JMS Client library. 29 | jar 30 | 31 | UTF-8 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | jakarta.jms 41 | jakarta.jms-api 42 | 43 | 44 | org.messaginghub 45 | pooled-jms 46 | 47 | 48 | org.slf4j 49 | slf4j-api 50 | 51 | 52 | 53 | 54 | 55 | 56 | org.junit.jupiter 57 | junit-jupiter-api 58 | test 59 | 60 | 61 | org.junit.jupiter 62 | junit-jupiter-engine 63 | test 64 | 65 | 66 | org.junit.jupiter 67 | junit-jupiter-params 68 | test 69 | 70 | 71 | org.slf4j 72 | slf4j-simple 73 | test 74 | 75 | 76 | org.apache.qpid 77 | qpid-jms-client 78 | test 79 | 80 | 81 | org.apache.activemq 82 | artemis-server 83 | test 84 | 85 | 86 | org.apache.activemq 87 | artemis-amqp-protocol 88 | test 89 | 90 | 91 | 92 | 93 | 94 | 95 | org.apache.maven.plugins 96 | maven-deploy-plugin 97 | 98 | true 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /pooled-jms-interop-tests/pooled-jms-qpid-jms-tests/src/test/java/org/messaginghub/pooled/jms/PooledConnectionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import static org.junit.jupiter.api.Assertions.fail; 20 | 21 | import jakarta.jms.Connection; 22 | import jakarta.jms.ConnectionFactory; 23 | import jakarta.jms.IllegalStateException; 24 | 25 | import org.junit.jupiter.api.Test; 26 | import org.junit.jupiter.api.Timeout; 27 | import org.slf4j.Logger; 28 | import org.slf4j.LoggerFactory; 29 | 30 | /** 31 | * A test against the PooledConnection class using QpidJMS 32 | */ 33 | @Timeout(60) 34 | public class PooledConnectionTest extends QpidJmsPoolTestSupport { 35 | 36 | private final Logger LOG = LoggerFactory.getLogger(PooledConnectionTest.class); 37 | 38 | @Test 39 | public void testSetClientIDTwiceWithSameID() throws Exception { 40 | // test: call setClientID("newID") twice 41 | // this should be tolerated and not result in an exception 42 | ConnectionFactory cf = createPooledConnectionFactory(); 43 | Connection conn = cf.createConnection(); 44 | conn.setClientID("newID"); 45 | 46 | try { 47 | conn.setClientID("newID"); 48 | conn.start(); 49 | conn.close(); 50 | } catch (IllegalStateException ise) { 51 | LOG.error("Repeated calls to newID2.setClientID(\"newID\") caused " + ise.getMessage()); 52 | fail("Repeated calls to newID2.setClientID(\"newID\") caused " + ise.getMessage()); 53 | } finally { 54 | ((JmsPoolConnectionFactory) cf).stop(); 55 | } 56 | 57 | LOG.debug("Test finished."); 58 | } 59 | 60 | @Test 61 | public void testSetClientIDTwiceWithDifferentID() throws Exception { 62 | ConnectionFactory cf = createPooledConnectionFactory(); 63 | Connection conn = cf.createConnection(); 64 | 65 | // test: call setClientID() twice with different IDs 66 | // this should result in an IllegalStateException 67 | conn.setClientID("newID1"); 68 | try { 69 | conn.setClientID("newID2"); 70 | fail("calling Connection.setClientID() twice with different clientID must raise an IllegalStateException"); 71 | } catch (IllegalStateException ise) { 72 | LOG.debug("Correctly received " + ise); 73 | } finally { 74 | conn.close(); 75 | ((JmsPoolConnectionFactory) cf).stop(); 76 | } 77 | 78 | LOG.debug("Test finished."); 79 | } 80 | 81 | @Test 82 | public void testSetClientIDAfterConnectionStart() throws Exception { 83 | ConnectionFactory cf = createPooledConnectionFactory(); 84 | Connection conn = cf.createConnection(); 85 | 86 | // test: try to call setClientID() after start() 87 | // should result in an exception 88 | try { 89 | conn.start(); 90 | conn.setClientID("newID3"); 91 | fail("Calling setClientID() after start() must raise a JMSException."); 92 | } catch (IllegalStateException ise) { 93 | LOG.debug("Correctly received " + ise); 94 | } finally { 95 | conn.close(); 96 | ((JmsPoolConnectionFactory) cf).stop(); 97 | } 98 | 99 | LOG.debug("Test finished."); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /pooled-jms-interop-tests/pooled-jms-qpid-jms-tests/src/test/java/org/messaginghub/pooled/jms/QpidJmsPoolTestSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import java.util.HashMap; 20 | import java.util.Map; 21 | import java.util.concurrent.TimeUnit; 22 | 23 | import org.apache.activemq.artemis.api.core.SimpleString; 24 | import org.apache.activemq.artemis.api.core.TransportConfiguration; 25 | import org.apache.activemq.artemis.core.config.Configuration; 26 | import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl; 27 | import org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory; 28 | import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants; 29 | import org.apache.activemq.artemis.core.server.ActiveMQServer; 30 | import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ; 31 | import org.apache.activemq.artemis.core.settings.impl.AddressSettings; 32 | import org.apache.activemq.artemis.spi.core.remoting.Acceptor; 33 | import org.apache.qpid.jms.JmsConnectionFactory; 34 | import org.junit.jupiter.api.AfterEach; 35 | import org.junit.jupiter.api.BeforeEach; 36 | import org.junit.jupiter.api.TestInfo; 37 | import org.messaginghub.pooled.jms.util.Wait; 38 | import org.slf4j.Logger; 39 | import org.slf4j.LoggerFactory; 40 | 41 | public class QpidJmsPoolTestSupport { 42 | 43 | protected static final Logger LOG = LoggerFactory.getLogger(QpidJmsPoolTestSupport.class); 44 | 45 | private static final String NETTY_ACCEPTOR = "netty-acceptor"; 46 | private static final String SERVER_NAME = "embedded-server"; 47 | 48 | protected String testName; 49 | protected String connectionURI; 50 | protected JmsConnectionFactory qpidJmsConnectionFactory; 51 | 52 | protected Configuration configuration; 53 | protected EmbeddedActiveMQ broker; 54 | 55 | @BeforeEach 56 | public void setUp(TestInfo info) throws Exception { 57 | LOG.info("========== start " + info.getDisplayName() + " =========="); 58 | 59 | testName = info.getDisplayName(); 60 | broker = createBroker(); 61 | 62 | qpidJmsConnectionFactory = new JmsConnectionFactory(connectionURI); 63 | } 64 | 65 | @AfterEach 66 | public void tearDown() throws Exception { 67 | if (broker != null) { 68 | try { 69 | broker.stop(); 70 | } catch (Exception ex) { 71 | LOG.warn("Suppress error on shutdown: {}", ex); 72 | } 73 | } 74 | 75 | LOG.info("========== tearDown " + getTestName() + " =========="); 76 | } 77 | 78 | public String getTestName() { 79 | return testName; 80 | } 81 | 82 | protected EmbeddedActiveMQ createBroker() throws Exception { 83 | Map params = new HashMap<>(); 84 | params.put(TransportConstants.PORT_PROP_NAME, 0); 85 | params.put(TransportConstants.PROTOCOLS_PROP_NAME, "AMQP"); 86 | 87 | TransportConfiguration tc = new TransportConfiguration(NettyAcceptorFactory.class.getName(), params, NETTY_ACCEPTOR); 88 | 89 | configuration = new ConfigurationImpl().setName(SERVER_NAME) 90 | .setPersistenceEnabled(false) 91 | .setSecurityEnabled(false) 92 | .addAcceptorConfiguration(tc) 93 | .addAddressesSetting("#", 94 | new AddressSettings().setDeadLetterAddress(SimpleString.of("dla")) 95 | .setExpiryAddress(SimpleString.of("expiry"))); 96 | broker = new EmbeddedActiveMQ().setConfiguration(configuration); 97 | broker.start(); 98 | 99 | ActiveMQServer server = broker.getActiveMQServer(); 100 | if(!server.waitForActivation(5000, TimeUnit.MILLISECONDS)) { 101 | throw new IllegalStateException("Server not activated within timeout"); 102 | } 103 | 104 | Acceptor acceptor = server.getRemotingService().getAcceptor(NETTY_ACCEPTOR); 105 | if(!Wait.waitFor(() -> acceptor.getActualPort() > 0, 5000, 20)) { 106 | throw new IllegalStateException("Acceptor port not determined within timeout"); 107 | } 108 | int actualPort = acceptor.getActualPort(); 109 | 110 | LOG.error("Acceptor was bound to port " + actualPort);//TODO: level 111 | 112 | connectionURI = "amqp://localhost:" + actualPort; 113 | 114 | return broker; 115 | } 116 | 117 | protected JmsPoolConnectionFactory createPooledConnectionFactory() { 118 | JmsPoolConnectionFactory cf = new JmsPoolConnectionFactory(); 119 | cf.setConnectionFactory(qpidJmsConnectionFactory); 120 | cf.setMaxConnections(1); 121 | LOG.debug("ConnectionFactory initialized."); 122 | return cf; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /pooled-jms-interop-tests/pooled-jms-qpid-jms-tests/src/test/java/org/messaginghub/pooled/jms/util/Wait.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.util; 18 | 19 | import java.util.concurrent.TimeUnit; 20 | 21 | public class Wait { 22 | 23 | public static final long MAX_WAIT_MILLIS = 30 * 1000; 24 | public static final long SLEEP_MILLIS = 200; 25 | 26 | public interface Condition { 27 | boolean isSatisfied() throws Exception; 28 | } 29 | 30 | public static boolean waitFor(Condition condition) throws Exception { 31 | return waitFor(condition, MAX_WAIT_MILLIS); 32 | } 33 | 34 | public static boolean waitFor(final Condition condition, final long duration) throws Exception { 35 | return waitFor(condition, duration, SLEEP_MILLIS); 36 | } 37 | 38 | public static boolean waitFor(final Condition condition, final long duration, final long sleepMillis) throws Exception { 39 | final long expiry = System.currentTimeMillis() + duration; 40 | boolean conditionSatisfied = condition.isSatisfied(); 41 | while (!conditionSatisfied && System.currentTimeMillis() < expiry) { 42 | TimeUnit.MILLISECONDS.sleep(sleepMillis); 43 | conditionSatisfied = condition.isSatisfied(); 44 | } 45 | return conditionSatisfied; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /pooled-jms-interop-tests/pooled-jms-qpid-jms-tests/src/test/resources/simplelogger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | org.slf4j.simpleLogger.logFile=System.out 20 | 21 | org.slf4j.simpleLogger.defaultLogLevel=trace 22 | 23 | org.slf4j.simpleLogger.showDateTime=true 24 | org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss,SSS 25 | 26 | org.slf4j.simpleLogger.log.org.messaginghub.pooled.jms=DEBUG 27 | 28 | -------------------------------------------------------------------------------- /pooled-jms/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 4.0.0 21 | 22 | 23 | org.messaginghub 24 | pooled-jms-parent 25 | 3.1.8-SNAPSHOT 26 | 27 | 28 | pooled-jms 29 | PooledJMS Library 30 | Generic JMS Pooled Connection library 31 | bundle 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | org.slf4j 40 | slf4j-api 41 | 42 | 43 | jakarta.jms 44 | jakarta.jms-api 45 | 46 | 47 | jakarta.transaction 48 | jakarta.transaction-api 49 | true 50 | 51 | 52 | org.apache.geronimo.components 53 | geronimo-transaction 54 | jakarta 55 | true 56 | 57 | 58 | org.apache.commons 59 | commons-pool2 60 | 61 | 62 | org.junit.jupiter 63 | junit-jupiter-api 64 | test 65 | 66 | 67 | org.junit.jupiter 68 | junit-jupiter-engine 69 | test 70 | 71 | 72 | org.junit.jupiter 73 | junit-jupiter-params 74 | test 75 | 76 | 77 | org.slf4j 78 | slf4j-simple 79 | test 80 | 81 | 82 | org.mockito 83 | mockito-core 84 | test 85 | 86 | 87 | 88 | 89 | 90 | 91 | org.apache.felix 92 | maven-bundle-plugin 93 | 94 | 95 | org.messaginghub.pooled.jms 96 | org.messaginghub.pooled.jms.* 97 | 98 | * 99 | * 100 | 101 | 102 | 103 | 104 | org.jacoco 105 | jacoco-maven-plugin 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | org.codehaus.mojo 114 | findbugs-maven-plugin 115 | ${findbugs-maven-plugin-version} 116 | 117 | Normal 118 | Default 119 | ${project.basedir}/src/site/findbugs-exclude.xml 120 | 121 | 122 | 123 | org.jacoco 124 | jacoco-maven-plugin 125 | ${jacoco-plugin-version} 126 | 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolJMSConsumer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import jakarta.jms.JMSConsumer; 20 | import jakarta.jms.JMSException; 21 | import jakarta.jms.JMSRuntimeException; 22 | import jakarta.jms.Message; 23 | import jakarta.jms.MessageListener; 24 | 25 | import org.messaginghub.pooled.jms.util.JMSExceptionSupport; 26 | 27 | /** 28 | * JMSConsumer implementation backed by a pooled Connection. 29 | */ 30 | public class JmsPoolJMSConsumer implements JMSConsumer, AutoCloseable { 31 | 32 | private final JmsPoolMessageConsumer consumer; 33 | 34 | public JmsPoolJMSConsumer(JmsPoolMessageConsumer consumer) { 35 | this.consumer = consumer; 36 | } 37 | 38 | @Override 39 | public void close() { 40 | try { 41 | consumer.close(); 42 | } catch (JMSException e) { 43 | throw JMSExceptionSupport.createRuntimeException(e); 44 | } 45 | } 46 | 47 | //----- MessageConsumer Property Methods ---------------------------------// 48 | 49 | @Override 50 | public MessageListener getMessageListener() { 51 | try { 52 | return consumer.getMessageListener(); 53 | } catch (JMSException e) { 54 | throw JMSExceptionSupport.createRuntimeException(e); 55 | } 56 | } 57 | 58 | @Override 59 | public String getMessageSelector() { 60 | try { 61 | return consumer.getMessageSelector(); 62 | } catch (JMSException e) { 63 | throw JMSExceptionSupport.createRuntimeException(e); 64 | } 65 | } 66 | 67 | @Override 68 | public void setMessageListener(MessageListener listener) { 69 | try { 70 | consumer.setMessageListener(listener); 71 | } catch (JMSException e) { 72 | throw JMSExceptionSupport.createRuntimeException(e); 73 | } 74 | } 75 | 76 | //----- Receive Methods --------------------------------------------------// 77 | 78 | @Override 79 | public Message receive() { 80 | try { 81 | return consumer.receive(); 82 | } catch (JMSException e) { 83 | throw JMSExceptionSupport.createRuntimeException(e); 84 | } 85 | } 86 | 87 | @Override 88 | public Message receive(long timeout) { 89 | try { 90 | return consumer.receive(timeout); 91 | } catch (JMSException e) { 92 | throw JMSExceptionSupport.createRuntimeException(e); 93 | } 94 | } 95 | 96 | @Override 97 | public Message receiveNoWait() { 98 | try { 99 | return consumer.receiveNoWait(); 100 | } catch (JMSException e) { 101 | throw JMSExceptionSupport.createRuntimeException(e); 102 | } 103 | } 104 | 105 | @Override 106 | public T receiveBody(Class desired) { 107 | throw new JMSRuntimeException("Pooled JMSConsumer does not support receiveBody"); 108 | } 109 | 110 | @Override 111 | public T receiveBody(Class desired, long timeout) { 112 | throw new JMSRuntimeException("Pooled JMSConsumer does not support receiveBody"); 113 | } 114 | 115 | @Override 116 | public T receiveBodyNoWait(Class desired) { 117 | throw new JMSRuntimeException("Pooled JMSConsumer does not support receiveBody"); 118 | } 119 | 120 | @Override 121 | public String toString() { 122 | return getClass().getSimpleName() + " { " + consumer + " }"; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolJcaConnectionFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import jakarta.jms.Connection; 20 | 21 | import org.messaginghub.pooled.jms.pool.PooledJCAConnection; 22 | 23 | public class JmsPoolJcaConnectionFactory extends JmsPoolXAConnectionFactory { 24 | 25 | private static final long serialVersionUID = -2470093537159318333L; 26 | 27 | private String name; 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | @Override 38 | protected PooledJCAConnection createPooledConnection(Connection connection) { 39 | return new PooledJCAConnection(connection, getTransactionManager(), getName()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolMessageConsumer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import java.util.concurrent.atomic.AtomicBoolean; 20 | 21 | import jakarta.jms.IllegalStateException; 22 | import jakarta.jms.JMSException; 23 | import jakarta.jms.Message; 24 | import jakarta.jms.MessageConsumer; 25 | import jakarta.jms.MessageListener; 26 | 27 | /** 28 | * A {@link MessageConsumer} which was created by {@link JmsPoolSession}. 29 | */ 30 | public class JmsPoolMessageConsumer implements MessageConsumer, AutoCloseable { 31 | 32 | private final JmsPoolSession session; 33 | private final MessageConsumer messageConsumer; 34 | private final AtomicBoolean closed = new AtomicBoolean(); 35 | 36 | /** 37 | * Wraps the message consumer. 38 | * 39 | * @param session 40 | * the pooled session 41 | * @param messageConsumer 42 | * the created consumer to wrap 43 | */ 44 | JmsPoolMessageConsumer(JmsPoolSession session, MessageConsumer messageConsumer) { 45 | this.session = session; 46 | this.messageConsumer = messageConsumer; 47 | } 48 | 49 | @Override 50 | public void close() throws JMSException { 51 | // ensure session removes consumer from it's list of managed resources. 52 | if (closed.compareAndSet(false, true)) { 53 | session.onConsumerClose(this); 54 | messageConsumer.close(); 55 | } 56 | } 57 | 58 | @Override 59 | public MessageListener getMessageListener() throws JMSException { 60 | checkClosed(); 61 | return messageConsumer.getMessageListener(); 62 | } 63 | 64 | @Override 65 | public String getMessageSelector() throws JMSException { 66 | checkClosed(); 67 | return messageConsumer.getMessageSelector(); 68 | } 69 | 70 | @Override 71 | public Message receive() throws JMSException { 72 | checkClosed(); 73 | return messageConsumer.receive(); 74 | } 75 | 76 | @Override 77 | public Message receive(long timeout) throws JMSException { 78 | checkClosed(); 79 | return messageConsumer.receive(timeout); 80 | } 81 | 82 | @Override 83 | public Message receiveNoWait() throws JMSException { 84 | checkClosed(); 85 | return messageConsumer.receiveNoWait(); 86 | } 87 | 88 | @Override 89 | public void setMessageListener(MessageListener listener) throws JMSException { 90 | checkClosed(); 91 | messageConsumer.setMessageListener(listener); 92 | } 93 | 94 | @Override 95 | public String toString() { 96 | return getClass().getSimpleName() + " { " + messageConsumer + " }"; 97 | } 98 | 99 | public MessageConsumer getMessageConsumer() throws JMSException { 100 | checkClosed(); 101 | return messageConsumer; 102 | } 103 | 104 | //----- Internal support methods -----------------------------------------// 105 | 106 | protected void checkClosed() throws JMSException { 107 | if (closed.get()) { 108 | throw new IllegalStateException("The MessageConsumer is closed"); 109 | } 110 | } 111 | 112 | protected MessageConsumer getDelegate() { 113 | return messageConsumer; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolQueueBrowser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import java.util.Enumeration; 20 | import java.util.concurrent.atomic.AtomicBoolean; 21 | 22 | import jakarta.jms.IllegalStateException; 23 | import jakarta.jms.JMSException; 24 | import jakarta.jms.Queue; 25 | import jakarta.jms.QueueBrowser; 26 | 27 | /** 28 | * A {@link QueueBrowser} which was created by {@link JmsPoolSession}. 29 | */ 30 | public class JmsPoolQueueBrowser implements QueueBrowser, AutoCloseable { 31 | 32 | private final AtomicBoolean closed = new AtomicBoolean(); 33 | 34 | private final JmsPoolSession session; 35 | private final QueueBrowser delegate; 36 | 37 | /** 38 | * Wraps the QueueBrowser. 39 | * 40 | * @param session 41 | * the pooled session that created this object. 42 | * @param delegate 43 | * the created QueueBrowser to wrap. 44 | */ 45 | public JmsPoolQueueBrowser(JmsPoolSession session, QueueBrowser delegate) { 46 | this.session = session; 47 | this.delegate = delegate; 48 | } 49 | 50 | @Override 51 | public Queue getQueue() throws JMSException { 52 | checkClosed(); 53 | return delegate.getQueue(); 54 | } 55 | 56 | @Override 57 | public String getMessageSelector() throws JMSException { 58 | checkClosed(); 59 | return delegate.getMessageSelector(); 60 | } 61 | 62 | @Override 63 | public Enumeration getEnumeration() throws JMSException { 64 | checkClosed(); 65 | return delegate.getEnumeration(); 66 | } 67 | 68 | @Override 69 | public void close() throws JMSException { 70 | if (closed.compareAndSet(false, true)) { 71 | // ensure session removes browser from it's list of managed resources. 72 | session.onQueueBrowserClose(this); 73 | delegate.close(); 74 | } 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | return getClass().getSimpleName() + " { " + delegate + " }"; 80 | } 81 | 82 | public QueueBrowser getQueueBrowser() throws JMSException { 83 | checkClosed(); 84 | return delegate; 85 | } 86 | 87 | private void checkClosed() throws IllegalStateException { 88 | if (closed.get()) { 89 | throw new IllegalStateException("The QueueBrowser is closed"); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolQueueReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import jakarta.jms.JMSException; 20 | import jakarta.jms.Queue; 21 | import jakarta.jms.QueueReceiver; 22 | 23 | /** 24 | * A {@link QueueReceiver} which was created by {@link JmsPoolSession}. 25 | */ 26 | public class JmsPoolQueueReceiver extends JmsPoolMessageConsumer implements QueueReceiver, AutoCloseable { 27 | 28 | /** 29 | * Wraps the QueueReceiver. 30 | * 31 | * @param session 32 | * the pooled session that created this object. 33 | * @param delegate 34 | * the created QueueReceiver to wrap. 35 | */ 36 | public JmsPoolQueueReceiver(JmsPoolSession session, QueueReceiver delegate) { 37 | super(session, delegate); 38 | } 39 | 40 | @Override 41 | public Queue getQueue() throws JMSException { 42 | return getQueueReceiver().getQueue(); 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return getClass().getSimpleName() + " { " + getDelegate() + " }"; 48 | } 49 | 50 | public QueueReceiver getQueueReceiver() throws JMSException { 51 | return (QueueReceiver) super.getMessageConsumer(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolQueueSender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import java.util.concurrent.atomic.AtomicInteger; 20 | 21 | import jakarta.jms.Destination; 22 | import jakarta.jms.JMSException; 23 | import jakarta.jms.Message; 24 | import jakarta.jms.Queue; 25 | import jakarta.jms.QueueSender; 26 | 27 | /** 28 | * {@link QueueSender} instance that is created and managed by the PooledConnection. 29 | */ 30 | public class JmsPoolQueueSender extends JmsPoolMessageProducer implements QueueSender, AutoCloseable { 31 | 32 | public JmsPoolQueueSender(JmsPoolSession session, QueueSender messageProducer, Destination destination, AtomicInteger refCount) throws JMSException { 33 | super(session, messageProducer, destination, refCount); 34 | } 35 | 36 | @Override 37 | public void send(Queue queue, Message message, int deliveryMode, int priority, long timeToLine) throws JMSException { 38 | super.send(queue, message, deliveryMode, priority, timeToLine); 39 | } 40 | 41 | @Override 42 | public void send(Queue queue, Message message) throws JMSException { 43 | super.send(queue, message); 44 | } 45 | 46 | @Override 47 | public Queue getQueue() throws JMSException { 48 | return (Queue) getDestination(); 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return getClass().getSimpleName() + " { " + getDelegate() + " }"; 54 | } 55 | 56 | public QueueSender getQueueSender() throws JMSException { 57 | return (QueueSender) getMessageProducer(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolSessionEventListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import jakarta.jms.TemporaryQueue; 20 | import jakarta.jms.TemporaryTopic; 21 | 22 | public interface JmsPoolSessionEventListener { 23 | 24 | /** 25 | * Called on successful creation of a new TemporaryQueue. 26 | * 27 | * @param tempQueue 28 | * The TemporaryQueue just created. 29 | */ 30 | void onTemporaryQueueCreate(TemporaryQueue tempQueue); 31 | 32 | /** 33 | * Called on successful creation of a new TemporaryTopic. 34 | * 35 | * @param tempTopic 36 | * The TemporaryTopic just created. 37 | */ 38 | void onTemporaryTopicCreate(TemporaryTopic tempTopic); 39 | 40 | /** 41 | * Called when the PooledSession is closed. 42 | * 43 | * @param session 44 | * The PooledSession that has been closed. 45 | */ 46 | void onSessionClosed(JmsPoolSession session); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolTopicPublisher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import java.util.concurrent.atomic.AtomicInteger; 20 | 21 | import jakarta.jms.Destination; 22 | import jakarta.jms.JMSException; 23 | import jakarta.jms.Message; 24 | import jakarta.jms.Topic; 25 | import jakarta.jms.TopicPublisher; 26 | 27 | /** 28 | * A {@link TopicPublisher} instance that is created and managed by a PooledConnection. 29 | */ 30 | public class JmsPoolTopicPublisher extends JmsPoolMessageProducer implements TopicPublisher, AutoCloseable { 31 | 32 | public JmsPoolTopicPublisher(JmsPoolSession session, TopicPublisher messageProducer, Destination destination, AtomicInteger refCount) throws JMSException { 33 | super(session, messageProducer, destination, refCount); 34 | } 35 | 36 | @Override 37 | public Topic getTopic() throws JMSException { 38 | return (Topic) getDestination(); 39 | } 40 | 41 | @Override 42 | public void publish(Message message) throws JMSException { 43 | super.send(message); 44 | } 45 | 46 | @Override 47 | public void publish(Message message, int deliveryMode, int priority, long timeToLive) throws JMSException { 48 | super.send(message, deliveryMode, priority, timeToLive); 49 | } 50 | 51 | @Override 52 | public void publish(Topic topic, Message message) throws JMSException { 53 | super.send(topic, message); 54 | } 55 | 56 | @Override 57 | public void publish(Topic topic, Message message, int deliveryMode, int priority, long timeToLive) throws JMSException { 58 | super.send(topic, message, deliveryMode, priority, timeToLive); 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return getClass().getSimpleName() + " { " + getDelegate() + " }"; 64 | } 65 | 66 | public TopicPublisher getTopicPublisher() throws JMSException { 67 | return (TopicPublisher) getMessageProducer(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolTopicSubscriber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import jakarta.jms.JMSException; 20 | import jakarta.jms.Topic; 21 | import jakarta.jms.TopicSubscriber; 22 | 23 | /** 24 | * A {@link TopicSubscriber} which was created by {@link JmsPoolSession}. 25 | */ 26 | public class JmsPoolTopicSubscriber extends JmsPoolMessageConsumer implements TopicSubscriber, AutoCloseable { 27 | 28 | /** 29 | * Wraps the TopicSubscriber. 30 | * 31 | * @param session 32 | * the pooled session that created this object. 33 | * @param delegate 34 | * the created QueueBrowser to wrap. 35 | */ 36 | public JmsPoolTopicSubscriber(JmsPoolSession session, TopicSubscriber delegate) { 37 | super(session, delegate); 38 | } 39 | 40 | @Override 41 | public Topic getTopic() throws JMSException { 42 | return getTopicSubscriber().getTopic(); 43 | } 44 | 45 | @Override 46 | public boolean getNoLocal() throws JMSException { 47 | return getTopicSubscriber().getNoLocal(); 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return getClass().getSimpleName() + " { " + getDelegate() + " }"; 53 | } 54 | 55 | public TopicSubscriber getTopicSubscriber() throws JMSException { 56 | return (TopicSubscriber) super.getMessageConsumer(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/JmsPoolXAJMSContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import jakarta.jms.JMSContext; 20 | import jakarta.jms.XAJMSContext; 21 | import javax.transaction.xa.XAResource; 22 | 23 | /** 24 | * XAJMSContext implementation that wraps a JmsPoolConnection 25 | */ 26 | public class JmsPoolXAJMSContext extends JmsPoolJMSContext implements XAJMSContext { 27 | 28 | public JmsPoolXAJMSContext(JmsPoolConnection connection, int sessionMode) { 29 | super(connection, sessionMode); 30 | } 31 | 32 | @Override 33 | public JMSContext getContext() { 34 | return this; 35 | } 36 | 37 | @Override 38 | public XAResource getXAResource() { 39 | return getSession().getXAResource(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/package.html: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 21 | A JMS provider which pools Connections and their associated resources. 22 | 23 | 24 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/pool/PooledConnectionKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.pool; 18 | 19 | /** 20 | * A cache key for the connection details 21 | */ 22 | public final class PooledConnectionKey { 23 | 24 | private final String userName; 25 | private final String password; 26 | private int hash; 27 | 28 | /** 29 | * Creates a new ConnectionKey using the supplied values. 30 | * 31 | * @param userName 32 | * The user name that this key represents 33 | * @param password 34 | * The password that this key represents 35 | */ 36 | public PooledConnectionKey(String userName, String password) { 37 | this.password = password; 38 | this.userName = userName; 39 | hash = 31; 40 | if (userName != null) { 41 | hash += userName.hashCode(); 42 | } 43 | hash *= 31; 44 | if (password != null) { 45 | hash += password.hashCode(); 46 | } 47 | } 48 | 49 | public String getPassword() { 50 | return password; 51 | } 52 | 53 | public String getUserName() { 54 | return userName; 55 | } 56 | 57 | @Override 58 | public int hashCode() { 59 | final int prime = 31; 60 | int result = 1; 61 | result = prime * result + hash; 62 | result = prime * result + ((password == null) ? 0 : password.hashCode()); 63 | result = prime * result + ((userName == null) ? 0 : userName.hashCode()); 64 | return result; 65 | } 66 | 67 | @Override 68 | public boolean equals(Object obj) { 69 | if (this == obj) { 70 | return true; 71 | } 72 | if (obj == null) { 73 | return false; 74 | } 75 | if (getClass() != obj.getClass()) { 76 | return false; 77 | } 78 | 79 | PooledConnectionKey other = (PooledConnectionKey) obj; 80 | if (hash != other.hash) { 81 | return false; 82 | } 83 | 84 | if (password == null) { 85 | if (other.password != null) { 86 | return false; 87 | } 88 | } else if (!password.equals(other.password)) { 89 | return false; 90 | } 91 | 92 | if (userName == null) { 93 | if (other.userName != null) { 94 | return false; 95 | } 96 | } else if (!userName.equals(other.userName)) { 97 | return false; 98 | } 99 | 100 | return true; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/pool/PooledJCAConnection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.pool; 18 | 19 | import jakarta.jms.Connection; 20 | import jakarta.jms.JMSException; 21 | import jakarta.jms.XASession; 22 | import jakarta.transaction.TransactionManager; 23 | import javax.transaction.xa.XAResource; 24 | 25 | import org.apache.geronimo.transaction.manager.WrapperNamedXAResource; 26 | import org.messaginghub.pooled.jms.JmsPoolSession; 27 | 28 | public class PooledJCAConnection extends PooledXAConnection { 29 | 30 | private final String name; 31 | 32 | public PooledJCAConnection(Connection connection, TransactionManager transactionManager, String name) { 33 | super(connection, transactionManager); 34 | this.name = name; 35 | } 36 | 37 | @Override 38 | protected XAResource createXaResource(JmsPoolSession session) throws JMSException { 39 | XAResource xares = ((XASession)session.getInternalSession()).getXAResource(); 40 | if (name != null) { 41 | xares = new WrapperNamedXAResource(xares, name); 42 | } 43 | return xares; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/pool/PooledSessionKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.pool; 18 | 19 | /** 20 | * A cache key for the session details used to locate PooledSession instances. 21 | */ 22 | public final class PooledSessionKey { 23 | 24 | private final boolean transacted; 25 | private final int ackMode; 26 | 27 | private int hash; 28 | 29 | public PooledSessionKey(boolean transacted, int ackMode) { 30 | this.transacted = transacted; 31 | this.ackMode = ackMode; 32 | this.hash = ackMode; 33 | 34 | if (transacted) { 35 | hash = 31 * hash + 1; 36 | } 37 | } 38 | 39 | @Override 40 | public int hashCode() { 41 | final int prime = 31; 42 | int result = 1; 43 | result = prime * result + ackMode; 44 | result = prime * result + hash; 45 | result = prime * result + (transacted ? 1231 : 1237); 46 | return result; 47 | } 48 | 49 | public boolean isTransacted() { 50 | return transacted; 51 | } 52 | 53 | public int getAckMode() { 54 | return ackMode; 55 | } 56 | 57 | @Override 58 | public boolean equals(Object obj) { 59 | if (this == obj) { 60 | return true; 61 | } 62 | if (obj == null) { 63 | return false; 64 | } 65 | if (getClass() != obj.getClass()) { 66 | return false; 67 | } 68 | 69 | PooledSessionKey other = (PooledSessionKey) obj; 70 | if (hash != other.hash) { 71 | return false; 72 | } 73 | 74 | if (ackMode != other.ackMode) { 75 | return false; 76 | } 77 | if (transacted != other.transacted) { 78 | return false; 79 | } 80 | 81 | return true; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/util/IntrospectionSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.util; 18 | 19 | import java.lang.reflect.Method; 20 | import java.util.Iterator; 21 | import java.util.Map; 22 | import java.util.Map.Entry; 23 | import javax.net.ssl.SSLServerSocket; 24 | import org.slf4j.Logger; 25 | import org.slf4j.LoggerFactory; 26 | 27 | public final class IntrospectionSupport { 28 | 29 | private static final Logger LOG = LoggerFactory.getLogger(IntrospectionSupport.class); 30 | 31 | private IntrospectionSupport() {} 32 | 33 | public static boolean setProperties(Object target, Map props) { 34 | boolean rc = false; 35 | 36 | if (target == null) { 37 | throw new IllegalArgumentException("target was null."); 38 | } 39 | if (props == null) { 40 | throw new IllegalArgumentException("props was null."); 41 | } 42 | 43 | for (Iterator iter = props.entrySet().iterator(); iter.hasNext();) { 44 | Entry entry = (Entry)iter.next(); 45 | if (setProperty(target, (String)entry.getKey(), entry.getValue())) { 46 | iter.remove(); 47 | rc = true; 48 | } 49 | } 50 | 51 | return rc; 52 | } 53 | 54 | public static boolean setProperty(Object target, String name, Object value) { 55 | try { 56 | Class clazz = target.getClass(); 57 | if (target instanceof SSLServerSocket) { 58 | // overcome illegal access issues with internal implementation class 59 | clazz = SSLServerSocket.class; 60 | } 61 | Method setter = findSetterMethod(clazz, name); 62 | if (setter == null) { 63 | return false; 64 | } 65 | 66 | // If the type is null or it matches the needed type, just use the 67 | // value directly 68 | if (value == null || value.getClass() == setter.getParameterTypes()[0]) { 69 | setter.invoke(target, value); 70 | } else { 71 | // We need to convert it 72 | setter.invoke(target, convert(value, setter.getParameterTypes()[0])); 73 | } 74 | return true; 75 | } catch (Exception e) { 76 | LOG.error(String.format("Could not set property %s on %s", name, target), e); 77 | return false; 78 | } 79 | } 80 | 81 | private static Object convert(Object value, Class to) { 82 | if (value == null) { 83 | // lets avoid NullPointerException when converting to boolean for null values 84 | if (boolean.class.isAssignableFrom(to)) { 85 | return Boolean.FALSE; 86 | } 87 | return null; 88 | } 89 | 90 | // eager same instance type test to avoid the overhead of invoking the type converter 91 | // if already same type 92 | if (to.isAssignableFrom(value.getClass())) { 93 | return to.cast(value); 94 | } 95 | 96 | if (boolean.class.isAssignableFrom(to) && value instanceof String) { 97 | return Boolean.valueOf((String)value); 98 | } 99 | 100 | throw new IllegalArgumentException("Cannot convert from " + value.getClass() 101 | + " to " + to + " with value " + value); 102 | } 103 | 104 | private static Method findSetterMethod(Class clazz, String name) { 105 | // Build the method name. 106 | name = "set" + Character.toUpperCase(name.charAt(0)) + name.substring(1); 107 | Method[] methods = clazz.getMethods(); 108 | for (Method method : methods) { 109 | Class params[] = method.getParameterTypes(); 110 | if (method.getName().equals(name) && params.length == 1 ) { 111 | return method; 112 | } 113 | } 114 | return null; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /pooled-jms/src/main/java/org/messaginghub/pooled/jms/util/LRUCache.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.util; 18 | 19 | import java.util.LinkedHashMap; 20 | import java.util.Map; 21 | 22 | /** 23 | * A Simple LRU Cache based on a LinkedHashMap. Not thread-safe. 24 | * 25 | * @param The type of the map key. 26 | * @param The type of the map value. 27 | */ 28 | public class LRUCache extends LinkedHashMap { 29 | 30 | private static final long serialVersionUID = -342098639681884413L; 31 | protected int maxCacheSize = 10000; 32 | 33 | /** 34 | * Default constructor for an LRU Cache The default capacity is 10000 35 | */ 36 | public LRUCache() { 37 | this(0,10000, 0.75f, true); 38 | } 39 | 40 | /** 41 | * Constructs a LRUCache with a maximum capacity 42 | * 43 | * @param maximumCacheSize 44 | * The maximum number of elements to keep in the Cache before eviction starts. 45 | */ 46 | public LRUCache(int maximumCacheSize) { 47 | this(0, maximumCacheSize, 0.75f, true); 48 | } 49 | 50 | /** 51 | * Constructs an empty {@link LRUCache} instance with the specified 52 | * initial capacity, maximumCacheSize,load factor and ordering mode. 53 | * 54 | * @param initialCapacity 55 | * The initial capacity. 56 | * @param maximumCacheSize 57 | * The maximum number of elements to keep in the Cache before eviction starts. 58 | * @param loadFactor 59 | * The load factor to configure on the underlying map. 60 | * @param accessOrder the ordering mode true for access-order, 61 | * false for insertion-order. 62 | * 63 | * @throws IllegalArgumentException if the initial capacity is negative or 64 | * the load factor is non-positive. 65 | */ 66 | public LRUCache(int initialCapacity, int maximumCacheSize, float loadFactor, boolean accessOrder) { 67 | super(initialCapacity, loadFactor, accessOrder); 68 | this.maxCacheSize = maximumCacheSize; 69 | } 70 | 71 | /** 72 | * @return Returns the maxCacheSize. 73 | */ 74 | public int getMaxCacheSize() { 75 | return maxCacheSize; 76 | } 77 | 78 | /** 79 | * @param maxCacheSize The maxCacheSize to set. 80 | */ 81 | public void setMaxCacheSize(int maxCacheSize) { 82 | this.maxCacheSize = maxCacheSize; 83 | } 84 | 85 | @Override 86 | protected boolean removeEldestEntry(Map.Entry eldest) { 87 | if( size() > maxCacheSize ) { 88 | onCacheEviction(eldest); 89 | return true; 90 | } 91 | return false; 92 | } 93 | 94 | /** 95 | * Event point used by subclasses to perform some cleanup action when an 96 | * element is evicted from the cache. 97 | * 98 | * @param eldest 99 | * the item being evicted from the LRUCache. 100 | */ 101 | protected void onCacheEviction(Map.Entry eldest) { 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /pooled-jms/src/site/findbugs-exclude.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/JmsPoolQueueReceiverTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertNotNull; 20 | import static org.junit.jupiter.api.Assertions.assertSame; 21 | import static org.junit.jupiter.api.Assertions.assertTrue; 22 | import static org.junit.jupiter.api.Assertions.fail; 23 | 24 | import jakarta.jms.IllegalStateException; 25 | import jakarta.jms.JMSException; 26 | import jakarta.jms.Queue; 27 | import jakarta.jms.QueueReceiver; 28 | import jakarta.jms.QueueSession; 29 | import jakarta.jms.Session; 30 | 31 | import org.junit.jupiter.api.Test; 32 | import org.junit.jupiter.api.Timeout; 33 | import org.messaginghub.pooled.jms.mock.MockJMSQueueReceiver; 34 | 35 | /** 36 | * Tests for the JMS Pool QueueReceiver wrapper 37 | */ 38 | @Timeout(60) 39 | public class JmsPoolQueueReceiverTest extends JmsPoolTestSupport { 40 | 41 | @Test 42 | public void testToString() throws JMSException { 43 | JmsPoolConnection connection = (JmsPoolConnection) cf.createQueueConnection(); 44 | QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 45 | Queue queue = session.createTemporaryQueue(); 46 | QueueReceiver receiver = session.createReceiver(queue); 47 | 48 | assertNotNull(receiver.toString()); 49 | } 50 | 51 | @Test 52 | public void testGetQueue() throws JMSException { 53 | JmsPoolConnection connection = (JmsPoolConnection) cf.createQueueConnection(); 54 | QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 55 | Queue queue = session.createTemporaryQueue(); 56 | QueueReceiver receiver = session.createReceiver(queue); 57 | 58 | assertNotNull(receiver.getQueue()); 59 | assertSame(queue, receiver.getQueue()); 60 | 61 | receiver.close(); 62 | 63 | try { 64 | receiver.getQueue(); 65 | fail("Cannot read topic on closed receiver"); 66 | } catch (IllegalStateException ise) {} 67 | } 68 | 69 | @Test 70 | public void testGetTopicSubscriber() throws JMSException { 71 | JmsPoolConnection connection = (JmsPoolConnection) cf.createQueueConnection(); 72 | QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 73 | Queue queue = session.createTemporaryQueue(); 74 | JmsPoolQueueReceiver receiver = (JmsPoolQueueReceiver) session.createReceiver(queue); 75 | 76 | assertNotNull(receiver.getQueueReceiver()); 77 | assertTrue(receiver.getQueueReceiver() instanceof MockJMSQueueReceiver); 78 | 79 | receiver.close(); 80 | 81 | try { 82 | receiver.getQueueReceiver(); 83 | fail("Cannot read state on closed receiver"); 84 | } catch (IllegalStateException ise) {} 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/JmsPoolReconnectOnFailureTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertNotSame; 20 | import static org.junit.jupiter.api.Assertions.assertTrue; 21 | import static org.junit.jupiter.api.Assertions.fail; 22 | 23 | import java.io.IOException; 24 | import java.util.concurrent.CountDownLatch; 25 | import java.util.concurrent.TimeUnit; 26 | 27 | import jakarta.jms.Connection; 28 | import jakarta.jms.ExceptionListener; 29 | import jakarta.jms.JMSException; 30 | import jakarta.jms.MessageProducer; 31 | import jakarta.jms.Queue; 32 | import jakarta.jms.Session; 33 | 34 | import org.junit.jupiter.api.BeforeEach; 35 | import org.junit.jupiter.api.Test; 36 | import org.junit.jupiter.api.TestInfo; 37 | import org.junit.jupiter.api.Timeout; 38 | import org.messaginghub.pooled.jms.mock.MockJMSConnection; 39 | import org.messaginghub.pooled.jms.mock.MockJMSConnectionFactory; 40 | import org.slf4j.Logger; 41 | import org.slf4j.LoggerFactory; 42 | 43 | @Timeout(60) 44 | public class JmsPoolReconnectOnFailureTest extends JmsPoolTestSupport { 45 | 46 | private static final Logger LOG = LoggerFactory.getLogger(JmsPoolReconnectOnFailureTest.class); 47 | 48 | @Override 49 | @BeforeEach 50 | public void setUp(TestInfo info) throws java.lang.Exception { 51 | super.setUp(info); 52 | 53 | factory = new MockJMSConnectionFactory(); 54 | 55 | cf = new JmsPoolConnectionFactory(); 56 | cf.setConnectionFactory(factory); 57 | cf.setMaxConnections(1); 58 | } 59 | 60 | @Test 61 | public void testConnectionCanBeCreatedAfterFailure() throws Exception { 62 | 63 | final CountDownLatch failed = new CountDownLatch(1); 64 | 65 | Connection connection = cf.createConnection(); 66 | LOG.info("Fetched new connection from the pool: {}", connection); 67 | connection.setExceptionListener(new ExceptionListener() { 68 | 69 | @Override 70 | public void onException(JMSException exception) { 71 | LOG.info("Pooled Connection failed"); 72 | failed.countDown(); 73 | } 74 | }); 75 | 76 | Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); 77 | Queue queue = session.createQueue("test"); 78 | MessageProducer producer = session.createProducer(queue); 79 | 80 | MockJMSConnection mockConnection = (MockJMSConnection) ((JmsPoolConnection) connection).getConnection(); 81 | mockConnection.injectConnectionFailure(new IOException("Lost connection")); 82 | 83 | assertTrue(failed.await(15, TimeUnit.SECONDS)); 84 | 85 | try { 86 | producer.send(session.createMessage()); 87 | fail("Should be disconnected"); 88 | } catch (JMSException ex) { 89 | LOG.info("Producer failed as expected: {}", ex.getMessage()); 90 | } 91 | 92 | Connection connection2 = cf.createConnection(); 93 | assertNotSame(connection, connection2); 94 | LOG.info("Fetched new connection from the pool: {}", connection2); 95 | session = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE); 96 | 97 | connection2.close(); 98 | 99 | cf.stop(); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/JmsPoolTestSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import org.junit.jupiter.api.AfterEach; 20 | import org.junit.jupiter.api.BeforeEach; 21 | import org.junit.jupiter.api.TestInfo; 22 | import org.messaginghub.pooled.jms.mock.MockJMSConnectionFactory; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | 26 | public class JmsPoolTestSupport { 27 | 28 | protected static final Logger LOG = LoggerFactory.getLogger(JmsPoolTestSupport.class); 29 | 30 | private String testName; 31 | 32 | protected MockJMSConnectionFactory factory; 33 | protected JmsPoolConnectionFactory cf; 34 | 35 | @BeforeEach 36 | public void setUp(TestInfo testInfo) throws Exception { 37 | LOG.info("========== start test: " + testInfo.getDisplayName() + " =========="); 38 | 39 | testName = testInfo.getDisplayName(); 40 | factory = new MockJMSConnectionFactory(); 41 | cf = new JmsPoolConnectionFactory(); 42 | cf.setConnectionFactory(factory); 43 | cf.setMaxConnections(1); 44 | } 45 | 46 | @AfterEach 47 | public void tearDown() throws Exception { 48 | try { 49 | cf.stop(); 50 | } catch (Exception ex) { 51 | // ignored 52 | } 53 | 54 | LOG.info("========== finished test " + getTestName()+ " =========="); 55 | } 56 | 57 | public String getTestName() { 58 | return testName; 59 | } 60 | } -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/JmsPoolTopicSubscriberTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertNotNull; 20 | import static org.junit.jupiter.api.Assertions.assertSame; 21 | import static org.junit.jupiter.api.Assertions.assertTrue; 22 | import static org.junit.jupiter.api.Assertions.fail; 23 | 24 | import jakarta.jms.IllegalStateException; 25 | import jakarta.jms.JMSException; 26 | import jakarta.jms.Session; 27 | import jakarta.jms.Topic; 28 | import jakarta.jms.TopicSession; 29 | import jakarta.jms.TopicSubscriber; 30 | 31 | import org.junit.jupiter.api.Test; 32 | import org.junit.jupiter.api.Timeout; 33 | import org.messaginghub.pooled.jms.mock.MockJMSTopicSubscriber; 34 | 35 | /** 36 | * Tests for the pool JMS TopicSubscriber wrapper. 37 | */ 38 | @Timeout(60) 39 | public class JmsPoolTopicSubscriberTest extends JmsPoolTestSupport { 40 | 41 | @Test 42 | public void testToString() throws JMSException { 43 | JmsPoolConnection connection = (JmsPoolConnection) cf.createTopicConnection(); 44 | TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); 45 | Topic topic = session.createTemporaryTopic(); 46 | TopicSubscriber subscriber = session.createSubscriber(topic); 47 | 48 | assertNotNull(subscriber.toString()); 49 | } 50 | 51 | @Test 52 | public void testGetTopic() throws JMSException { 53 | JmsPoolConnection connection = (JmsPoolConnection) cf.createTopicConnection(); 54 | TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); 55 | Topic topic = session.createTemporaryTopic(); 56 | TopicSubscriber subscriber = session.createSubscriber(topic); 57 | 58 | assertNotNull(subscriber.getTopic()); 59 | assertSame(topic, subscriber.getTopic()); 60 | 61 | subscriber.close(); 62 | 63 | try { 64 | subscriber.getTopic(); 65 | fail("Cannot read topic on closed subscriber"); 66 | } catch (IllegalStateException ise) {} 67 | } 68 | 69 | @Test 70 | public void testGetNoLocal() throws JMSException { 71 | JmsPoolConnection connection = (JmsPoolConnection) cf.createTopicConnection(); 72 | TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); 73 | Topic topic = session.createTemporaryTopic(); 74 | TopicSubscriber subscriber = session.createDurableSubscriber(topic, "name", "color = red", true); 75 | 76 | assertTrue(subscriber.getNoLocal()); 77 | 78 | subscriber.close(); 79 | 80 | try { 81 | subscriber.getNoLocal(); 82 | fail("Cannot read state on closed subscriber"); 83 | } catch (IllegalStateException ise) {} 84 | } 85 | 86 | @Test 87 | public void testGetTopicSubscriber() throws JMSException { 88 | JmsPoolConnection connection = (JmsPoolConnection) cf.createTopicConnection(); 89 | TopicSession session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); 90 | Topic topic = session.createTemporaryTopic(); 91 | JmsPoolTopicSubscriber subscriber = (JmsPoolTopicSubscriber) session.createDurableSubscriber(topic, "name", "color = red", true); 92 | 93 | assertNotNull(subscriber.getTopicSubscriber()); 94 | assertTrue(subscriber.getTopicSubscriber() instanceof MockJMSTopicSubscriber); 95 | 96 | subscriber.close(); 97 | 98 | try { 99 | subscriber.getTopicSubscriber(); 100 | fail("Cannot read state on closed subscriber"); 101 | } catch (IllegalStateException ise) {} 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/JmsPoolXAConnectionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertEquals; 20 | import static org.junit.jupiter.api.Assertions.assertNotNull; 21 | import static org.junit.jupiter.api.Assertions.assertSame; 22 | import static org.junit.jupiter.api.Assertions.assertThrows; 23 | import static org.mockito.ArgumentMatchers.any; 24 | import static org.mockito.Mockito.doThrow; 25 | import static org.mockito.Mockito.when; 26 | 27 | import org.junit.jupiter.api.AfterEach; 28 | import org.junit.jupiter.api.BeforeEach; 29 | import org.junit.jupiter.api.Test; 30 | import org.junit.jupiter.api.TestInfo; 31 | import org.messaginghub.pooled.jms.mock.MockJMSConnectionMetaData; 32 | import org.messaginghub.pooled.jms.mock.MockJMSXAConnectionFactory; 33 | import org.mockito.Mock; 34 | import org.mockito.MockitoAnnotations; 35 | 36 | import jakarta.jms.Connection; 37 | import jakarta.jms.ConnectionMetaData; 38 | import jakarta.jms.JMSException; 39 | import jakarta.jms.XASession; 40 | import jakarta.transaction.RollbackException; 41 | import jakarta.transaction.Transaction; 42 | import jakarta.transaction.TransactionManager; 43 | 44 | /** 45 | * Tests for the XA pooled connection handling. 46 | */ 47 | class JmsPoolXAConnectionTest extends JmsPoolTestSupport { 48 | 49 | protected JmsPoolXAConnectionFactory xaCF; 50 | 51 | @Mock 52 | TransactionManager txManager; 53 | 54 | @Mock 55 | Transaction txn; 56 | 57 | @BeforeEach 58 | public void setUp() { 59 | } 60 | 61 | @Override 62 | @BeforeEach 63 | public void setUp(TestInfo testInfo) throws Exception { 64 | super.setUp(testInfo); 65 | 66 | MockitoAnnotations.openMocks(this); 67 | 68 | when(txManager.getTransaction()).thenReturn(txn); 69 | when(txn.enlistResource(any())).thenReturn(true); 70 | 71 | factory = new MockJMSXAConnectionFactory(); 72 | 73 | xaCF = new JmsPoolXAConnectionFactory(); 74 | xaCF.setTransactionManager(txManager); 75 | xaCF.setConnectionFactory(factory); 76 | xaCF.setMaxConnections(1); 77 | } 78 | 79 | @Override 80 | @AfterEach 81 | public void tearDown() throws Exception { 82 | try { 83 | xaCF.stop(); 84 | } catch (Exception ex) { 85 | // ignored 86 | } 87 | 88 | super.tearDown(); 89 | } 90 | 91 | @Test 92 | public void testGetConnectionMetaData() throws Exception { 93 | Connection connection = xaCF.createConnection(); 94 | ConnectionMetaData metaData = connection.getMetaData(); 95 | 96 | assertNotNull(metaData); 97 | assertSame(metaData, MockJMSConnectionMetaData.INSTANCE); 98 | } 99 | 100 | @Test 101 | public void testCreateXASession() throws Exception { 102 | JmsPoolConnection connection = (JmsPoolConnection) xaCF.createConnection(); 103 | XASession session = (XASession) connection.createSession(); 104 | 105 | when(txn.enlistResource(any())).thenReturn(true); 106 | 107 | assertNotNull(session); 108 | 109 | assertEquals(0, connection.getNumtIdleSessions()); 110 | session.close(); 111 | 112 | // Session should be ignoring close at this stage 113 | assertEquals(0, connection.getNumtIdleSessions()); 114 | } 115 | 116 | @Test 117 | public void testCreateXASessionFailsOnAddSynchronization() throws Exception { 118 | JmsPoolConnection connection = (JmsPoolConnection) xaCF.createConnection(); 119 | 120 | doThrow(RollbackException.class).when(txn).registerSynchronization(any()); 121 | when(txn.enlistResource(any())).thenReturn(true); 122 | 123 | assertThrows(JMSException.class, () -> connection.createSession()); 124 | 125 | // Session should be invalidated as we don't know the state after failed register 126 | assertEquals(0, connection.getNumtIdleSessions()); 127 | } 128 | 129 | @Test 130 | public void testCreateXASessionFailsOnEnlist() throws Exception { 131 | JmsPoolConnection connection = (JmsPoolConnection) xaCF.createConnection(); 132 | 133 | when(txn.enlistResource(any())).thenReturn(false); 134 | 135 | assertThrows(JMSException.class, () -> connection.createSession()); 136 | 137 | // Session should be invalidated as we don't know the state after failed enlist 138 | assertEquals(0, connection.getNumtIdleSessions()); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/JmsQueueBrowserTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms; 18 | 19 | import static org.junit.jupiter.api.Assertions.assertEquals; 20 | import static org.junit.jupiter.api.Assertions.assertNotNull; 21 | import static org.junit.jupiter.api.Assertions.fail; 22 | 23 | import jakarta.jms.IllegalStateException; 24 | import jakarta.jms.JMSException; 25 | import jakarta.jms.Queue; 26 | import jakarta.jms.QueueBrowser; 27 | import jakarta.jms.QueueSession; 28 | import jakarta.jms.Session; 29 | 30 | import org.junit.jupiter.api.Test; 31 | import org.junit.jupiter.api.Timeout; 32 | 33 | /** 34 | * Tests for the JMS Pool QueueBrowser wrapper 35 | */ 36 | @Timeout(60) 37 | public class JmsQueueBrowserTest extends JmsPoolTestSupport { 38 | 39 | @Test 40 | public void testToString() throws JMSException { 41 | JmsPoolConnection connection = (JmsPoolConnection) cf.createQueueConnection(); 42 | QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 43 | Queue queue = session.createTemporaryQueue(); 44 | QueueBrowser browser = session.createBrowser(queue); 45 | 46 | assertNotNull(browser.toString()); 47 | } 48 | 49 | @Test 50 | public void testGetQueue() throws JMSException { 51 | JmsPoolConnection connection = (JmsPoolConnection) cf.createQueueConnection(); 52 | QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 53 | Queue queue = session.createTemporaryQueue(); 54 | QueueBrowser browser = session.createBrowser(queue); 55 | 56 | assertNotNull(browser.getQueue()); 57 | 58 | browser.close(); 59 | browser.close(); 60 | 61 | try { 62 | browser.getQueue(); 63 | fail("Should not be able to use a closed browser"); 64 | } catch (IllegalStateException ise) { 65 | } 66 | } 67 | 68 | @Test 69 | public void testGetQueueBrowser() throws JMSException { 70 | JmsPoolConnection connection = (JmsPoolConnection) cf.createQueueConnection(); 71 | QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 72 | Queue queue = session.createTemporaryQueue(); 73 | JmsPoolQueueBrowser browser = (JmsPoolQueueBrowser) session.createBrowser(queue); 74 | 75 | assertNotNull(browser.getQueueBrowser()); 76 | 77 | browser.close(); 78 | 79 | try { 80 | browser.getQueueBrowser(); 81 | fail("Should not be able to use a closed browser"); 82 | } catch (IllegalStateException ise) { 83 | } 84 | } 85 | 86 | @Test 87 | public void testGetMessageSelector() throws JMSException { 88 | JmsPoolConnection connection = (JmsPoolConnection) cf.createQueueConnection(); 89 | QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 90 | Queue queue = session.createTemporaryQueue(); 91 | QueueBrowser browser = session.createBrowser(queue, "color = red"); 92 | 93 | assertNotNull(browser.getMessageSelector()); 94 | assertEquals("color = red", browser.getMessageSelector()); 95 | 96 | browser.close(); 97 | 98 | try { 99 | browser.getMessageSelector(); 100 | fail("Should not be able to use a closed browser"); 101 | } catch (IllegalStateException ise) { 102 | } 103 | } 104 | 105 | @Test 106 | public void testGetEnumeration() throws JMSException { 107 | JmsPoolConnection connection = (JmsPoolConnection) cf.createQueueConnection(); 108 | QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); 109 | Queue queue = session.createTemporaryQueue(); 110 | QueueBrowser browser = session.createBrowser(queue); 111 | 112 | assertNotNull(browser.getEnumeration()); 113 | 114 | browser.close(); 115 | 116 | try { 117 | browser.getEnumeration(); 118 | fail("Should not be able to use a closed browser"); 119 | } catch (IllegalStateException ise) { 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSConnectionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.JMSException; 20 | import jakarta.jms.Message; 21 | 22 | /** 23 | * Listen in on events in the MockJMSConnection and influence outcomes 24 | */ 25 | public interface MockJMSConnectionListener { 26 | 27 | void onCreateTemporaryQueue(MockJMSTemporaryQueue queue) throws JMSException; 28 | 29 | void onDeleteTemporaryQueue(MockJMSTemporaryQueue queue) throws JMSException; 30 | 31 | void onCreateTemporaryTopic(MockJMSTemporaryTopic topic) throws JMSException; 32 | 33 | void onDeleteTemporaryTopic(MockJMSTemporaryTopic topic) throws JMSException; 34 | 35 | void onCreateSession(MockJMSSession session) throws JMSException; 36 | 37 | void onCloseSession(MockJMSSession session) throws JMSException; 38 | 39 | void onMessageSend(MockJMSSession session, MockJMSMessageProducer producer, Message message) throws JMSException; 40 | 41 | void onCreateMessageConsumer(MockJMSSession session, MockJMSMessageConsumer consumer) throws JMSException; 42 | 43 | void onCloseMessageConsumer(MockJMSSession session, MockJMSMessageConsumer consumer) throws JMSException; 44 | 45 | void onCreateMessageProducer(MockJMSSession session, MockJMSMessageProducer producer) throws JMSException; 46 | 47 | void onCloseMessageProducer(MockJMSSession session, MockJMSMessageProducer producer) throws JMSException; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSConnectionMetaData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import java.util.Enumeration; 20 | 21 | import jakarta.jms.ConnectionMetaData; 22 | import jakarta.jms.JMSException; 23 | 24 | /** 25 | * Mock JMS Connection Meta-Data 26 | */ 27 | public class MockJMSConnectionMetaData implements ConnectionMetaData { 28 | 29 | public static final MockJMSConnectionMetaData INSTANCE = new MockJMSConnectionMetaData(); 30 | 31 | private MockJMSConnectionMetaData() { 32 | // Use the INSTANCE 33 | } 34 | 35 | @Override 36 | public String getJMSVersion() throws JMSException { 37 | return "3.1"; 38 | } 39 | 40 | @Override 41 | public int getJMSMajorVersion() throws JMSException { 42 | return 3; 43 | } 44 | 45 | @Override 46 | public int getJMSMinorVersion() throws JMSException { 47 | return 1; 48 | } 49 | 50 | @Override 51 | public String getJMSProviderName() throws JMSException { 52 | return "MockJMS"; 53 | } 54 | 55 | @Override 56 | public String getProviderVersion() throws JMSException { 57 | return "1.0"; 58 | } 59 | 60 | @Override 61 | public int getProviderMajorVersion() throws JMSException { 62 | return 1; 63 | } 64 | 65 | @Override 66 | public int getProviderMinorVersion() throws JMSException { 67 | return 0; 68 | } 69 | 70 | @Override 71 | public Enumeration getJMSXPropertyNames() throws JMSException { 72 | return null; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSConnectionStats.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import java.util.HashSet; 20 | import java.util.Set; 21 | import java.util.concurrent.atomic.AtomicLong; 22 | 23 | /** 24 | * Collects statistics about the state and usage of the MockJMSConnection 25 | */ 26 | public class MockJMSConnectionStats { 27 | 28 | private final Set temporaryQueues = new HashSet<>(); 29 | private final Set temporaryTopics = new HashSet<>(); 30 | 31 | private final AtomicLong totalTempQueues = new AtomicLong(); 32 | private final AtomicLong totalTempTopics = new AtomicLong(); 33 | 34 | public void temporaryDestinationCreated(MockJMSTemporaryDestination destination) { 35 | if (destination.isQueue()) { 36 | totalTempQueues.incrementAndGet(); 37 | temporaryQueues.add((MockJMSTemporaryQueue) destination); 38 | } else { 39 | totalTempTopics.incrementAndGet(); 40 | temporaryTopics.add((MockJMSTemporaryTopic) destination); 41 | } 42 | } 43 | 44 | public void temporaryDestinationDestroyed(MockJMSTemporaryDestination destination) { 45 | if (destination.isQueue()) { 46 | temporaryQueues.remove(destination); 47 | } else { 48 | temporaryTopics.remove(destination); 49 | } 50 | } 51 | 52 | public long getActiveTemporaryQueueCount() { 53 | return temporaryQueues.size(); 54 | } 55 | 56 | public long getActiveTemporaryTopicCount() { 57 | return temporaryTopics.size(); 58 | } 59 | 60 | public long getTotalTemporaryQueuesCreated() { 61 | return totalTempQueues.get(); 62 | } 63 | 64 | public long getTotalTemporaryTopicsCreated() { 65 | return totalTempTopics.get(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSConsumer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.JMSConsumer; 20 | import jakarta.jms.JMSException; 21 | import jakarta.jms.Message; 22 | import jakarta.jms.MessageListener; 23 | 24 | import org.messaginghub.pooled.jms.util.JMSExceptionSupport; 25 | 26 | @SuppressWarnings("unused") 27 | public class MockJMSConsumer implements JMSConsumer, AutoCloseable { 28 | 29 | private final MockJMSSession session; 30 | private final MockJMSMessageConsumer consumer; 31 | 32 | public MockJMSConsumer(MockJMSSession session, MockJMSMessageConsumer consumer) { 33 | this.session = session; 34 | this.consumer = consumer; 35 | } 36 | 37 | @Override 38 | public void close() { 39 | try { 40 | consumer.close(); 41 | } catch (JMSException e) { 42 | throw JMSExceptionSupport.createRuntimeException(e); 43 | } 44 | } 45 | 46 | //----- MessageConsumer Property Methods ---------------------------------// 47 | 48 | @Override 49 | public MessageListener getMessageListener() { 50 | try { 51 | return consumer.getMessageListener(); 52 | } catch (JMSException e) { 53 | throw JMSExceptionSupport.createRuntimeException(e); 54 | } 55 | } 56 | 57 | @Override 58 | public String getMessageSelector() { 59 | try { 60 | return consumer.getMessageSelector(); 61 | } catch (JMSException e) { 62 | throw JMSExceptionSupport.createRuntimeException(e); 63 | } 64 | } 65 | 66 | @Override 67 | public void setMessageListener(MessageListener listener) { 68 | try { 69 | consumer.setMessageListener(listener); 70 | } catch (JMSException e) { 71 | throw JMSExceptionSupport.createRuntimeException(e); 72 | } 73 | } 74 | 75 | //----- Receive Methods --------------------------------------------------// 76 | 77 | @Override 78 | public Message receive() { 79 | try { 80 | return consumer.receive(); 81 | } catch (JMSException e) { 82 | throw JMSExceptionSupport.createRuntimeException(e); 83 | } 84 | } 85 | 86 | @Override 87 | public Message receive(long timeout) { 88 | try { 89 | return consumer.receive(timeout); 90 | } catch (JMSException e) { 91 | throw JMSExceptionSupport.createRuntimeException(e); 92 | } 93 | } 94 | 95 | @Override 96 | public Message receiveNoWait() { 97 | try { 98 | return consumer.receiveNoWait(); 99 | } catch (JMSException e) { 100 | throw JMSExceptionSupport.createRuntimeException(e); 101 | } 102 | } 103 | 104 | @Override 105 | public T receiveBody(Class desired) { 106 | try { 107 | return consumer.receiveBody(desired, -1); 108 | } catch (JMSException e) { 109 | throw JMSExceptionSupport.createRuntimeException(e); 110 | } 111 | } 112 | 113 | @Override 114 | public T receiveBody(Class desired, long timeout) { 115 | try { 116 | // Configure for infinite wait when timeout is zero (JMS Spec) 117 | if (timeout == 0) { 118 | timeout = -1; 119 | } 120 | 121 | return consumer.receiveBody(desired, timeout); 122 | } catch (JMSException e) { 123 | throw JMSExceptionSupport.createRuntimeException(e); 124 | } 125 | } 126 | 127 | @Override 128 | public T receiveBodyNoWait(Class desired) { 129 | try { 130 | return consumer.receiveBody(desired, 0); 131 | } catch (JMSException e) { 132 | throw JMSExceptionSupport.createRuntimeException(e); 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSDefaultConnectionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.JMSException; 20 | import jakarta.jms.Message; 21 | 22 | public class MockJMSDefaultConnectionListener implements MockJMSConnectionListener { 23 | 24 | @Override 25 | public void onCreateTemporaryQueue(MockJMSTemporaryQueue queue) throws JMSException {} 26 | 27 | @Override 28 | public void onDeleteTemporaryQueue(MockJMSTemporaryQueue queue) throws JMSException {} 29 | 30 | @Override 31 | public void onCreateTemporaryTopic(MockJMSTemporaryTopic topic) throws JMSException {} 32 | 33 | @Override 34 | public void onDeleteTemporaryTopic(MockJMSTemporaryTopic topic) throws JMSException {} 35 | 36 | @Override 37 | public void onCreateSession(MockJMSSession session) throws JMSException {} 38 | 39 | @Override 40 | public void onCloseSession(MockJMSSession session) throws JMSException {} 41 | 42 | @Override 43 | public void onMessageSend(MockJMSSession session, MockJMSMessageProducer producer, Message message) throws JMSException {} 44 | 45 | @Override 46 | public void onCreateMessageConsumer(MockJMSSession session, MockJMSMessageConsumer consumer) throws JMSException {} 47 | 48 | @Override 49 | public void onCloseMessageConsumer(MockJMSSession session, MockJMSMessageConsumer consumer) throws JMSException {} 50 | 51 | @Override 52 | public void onCreateMessageProducer(MockJMSSession session, MockJMSMessageProducer producer) throws JMSException {} 53 | 54 | @Override 55 | public void onCloseMessageProducer(MockJMSSession session, MockJMSMessageProducer producer) throws JMSException {} 56 | 57 | } 58 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSDefaultSessionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.JMSException; 20 | 21 | public class MockJMSDefaultSessionListener implements MockJMSSessionListener { 22 | 23 | @Override 24 | public void onSessionCommit(MockJMSSession session) throws JMSException {} 25 | 26 | @Override 27 | public void onSessionRollback(MockJMSSession session) throws JMSException {} 28 | 29 | @Override 30 | public void onSessionClosed(MockJMSSession session) throws JMSException {} 31 | 32 | @Override 33 | public void onConsumerClose(MockJMSSession session, MockJMSMessageConsumer consumer) throws JMSException {} 34 | 35 | @Override 36 | public void onProducerClose(MockJMSSession session, MockJMSMessageProducer producer) throws JMSException {} 37 | 38 | } 39 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSDestination.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | /** 20 | * Mock JMS Destination implementation 21 | */ 22 | public abstract class MockJMSDestination implements jakarta.jms.Destination, Comparable { 23 | 24 | protected transient String name; 25 | protected transient boolean topic; 26 | protected transient boolean temporary; 27 | protected transient int hashValue; 28 | protected transient MockJMSConnection connection; 29 | 30 | protected MockJMSDestination(String name, boolean topic, boolean temporary) { 31 | this.name = name; 32 | this.topic = topic; 33 | this.temporary = temporary; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return name; 39 | } 40 | 41 | /** 42 | * @return name of destination 43 | */ 44 | public String getName() { 45 | return this.name; 46 | } 47 | 48 | public void setName(String name) { 49 | this.name = name; 50 | } 51 | 52 | /** 53 | * @return the topic 54 | */ 55 | public boolean isTopic() { 56 | return this.topic; 57 | } 58 | 59 | /** 60 | * @return the temporary 61 | */ 62 | public boolean isTemporary() { 63 | return this.temporary; 64 | } 65 | 66 | /** 67 | * @return true if a Topic 68 | */ 69 | public boolean isQueue() { 70 | return !this.topic; 71 | } 72 | 73 | /** 74 | * @param other 75 | * the Object to be compared. 76 | * @return a negative integer, zero, or a positive integer as this object is 77 | * less than, equal to, or greater than the specified object. 78 | * @see java.lang.Comparable#compareTo(java.lang.Object) 79 | */ 80 | @Override 81 | public int compareTo(MockJMSDestination other) { 82 | if (other != null) { 83 | if (this == other) { 84 | return 0; 85 | } 86 | if (isTemporary() == other.isTemporary()) { 87 | return getName().compareTo(other.getName()); 88 | } 89 | return -1; 90 | } 91 | return -1; 92 | } 93 | 94 | @Override 95 | public boolean equals(Object o) { 96 | if (this == o) { 97 | return true; 98 | } 99 | if (o == null || getClass() != o.getClass()) { 100 | return false; 101 | } 102 | 103 | MockJMSDestination other = (MockJMSDestination) o; 104 | if (name == null && other.name != null) { 105 | return false; 106 | } else if (name != null && !name.equals(other.name)) { 107 | return false; 108 | } 109 | 110 | if (temporary != other.temporary) { 111 | return false; 112 | } 113 | if (topic != other.topic) { 114 | return false; 115 | } 116 | 117 | return true; 118 | } 119 | 120 | @Override 121 | public int hashCode() { 122 | if (hashValue == 0) { 123 | final int prime = 31; 124 | hashValue = 1; 125 | hashValue = prime * hashValue + ((name == null) ? 0 : name.hashCode()); 126 | hashValue = prime * hashValue + (temporary ? 1231 : 1237); 127 | hashValue = prime * hashValue + (topic ? 1231 : 1237); 128 | } 129 | return hashValue; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSMessageConsumer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import java.util.concurrent.atomic.AtomicBoolean; 20 | 21 | import jakarta.jms.IllegalStateException; 22 | import jakarta.jms.JMSException; 23 | import jakarta.jms.Message; 24 | import jakarta.jms.MessageConsumer; 25 | import jakarta.jms.MessageListener; 26 | 27 | /** 28 | * Mock JMS MessageConsumer implementation. 29 | */ 30 | public class MockJMSMessageConsumer implements MessageConsumer, AutoCloseable { 31 | 32 | protected final MockJMSSession session; 33 | protected final String consumerId; 34 | protected final MockJMSDestination destination; 35 | protected final String messageSelector; 36 | protected final boolean noLocal; 37 | 38 | private final AtomicBoolean closed = new AtomicBoolean(); 39 | 40 | private MessageListener messageListener; 41 | 42 | public MockJMSMessageConsumer(MockJMSSession session, String consumerId, MockJMSDestination destination, String messageSelector, boolean noLocal) throws JMSException { 43 | this.session = session; 44 | this.consumerId = consumerId; 45 | this.destination = destination; 46 | this.messageSelector = messageSelector; 47 | this.noLocal = noLocal; 48 | 49 | MockJMSConnection connection = session.getConnection(); 50 | connection.getUser().checkCanConsume(destination); 51 | 52 | session.add(this); 53 | } 54 | 55 | @Override 56 | public void close() throws JMSException { 57 | if (closed.compareAndSet(false, true)) { 58 | session.remove(this); 59 | } 60 | } 61 | 62 | void start() { 63 | // TODO Auto-generated method stub 64 | } 65 | 66 | //----- Consumer Configuration Methods -----------------------------------// 67 | 68 | @Override 69 | public String getMessageSelector() throws JMSException { 70 | checkClosed(); 71 | return messageSelector; 72 | } 73 | 74 | @Override 75 | public MessageListener getMessageListener() throws JMSException { 76 | checkClosed(); 77 | return messageListener; 78 | } 79 | 80 | @Override 81 | public void setMessageListener(MessageListener listener) throws JMSException { 82 | checkClosed(); 83 | this.messageListener = listener; 84 | } 85 | 86 | //----- Message Receive Methods ------------------------------------------// 87 | 88 | @Override 89 | public Message receive() throws JMSException { 90 | checkClosed(); 91 | // TODO Auto-generated method stub 92 | return null; 93 | } 94 | 95 | @Override 96 | public Message receive(long timeout) throws JMSException { 97 | checkClosed(); 98 | // TODO Auto-generated method stub 99 | return null; 100 | } 101 | 102 | @Override 103 | public Message receiveNoWait() throws JMSException { 104 | checkClosed(); 105 | // TODO Auto-generated method stub 106 | return null; 107 | } 108 | 109 | public T receiveBody(Class desired, long timeout) throws JMSException { 110 | checkClosed(); 111 | //checkMessageListener(); 112 | // TODO Auto-generated method stub 113 | return null; 114 | } 115 | 116 | //----- Internal Support Methods -----------------------------------------// 117 | 118 | protected void checkClosed() throws IllegalStateException { 119 | if (closed.get()) { 120 | throw new IllegalStateException("The MessageProducer is closed"); 121 | } 122 | } 123 | 124 | public String getConsumerId() { 125 | return consumerId; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSObjectMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import java.io.Serializable; 20 | 21 | import jakarta.jms.JMSException; 22 | import jakarta.jms.MessageFormatException; 23 | import jakarta.jms.ObjectMessage; 24 | 25 | /** 26 | * Mock JMS ObjectMessage implementation. 27 | */ 28 | public class MockJMSObjectMessage extends MockJMSMessage implements ObjectMessage { 29 | 30 | private Serializable object; 31 | 32 | @Override 33 | public void setObject(Serializable object) throws JMSException { 34 | this.object = object; 35 | } 36 | 37 | @Override 38 | public Serializable getObject() throws JMSException { 39 | return object; 40 | } 41 | 42 | @Override 43 | public boolean isBodyAssignableTo(@SuppressWarnings("rawtypes") Class target) throws JMSException { 44 | if (object == null) { 45 | return true; 46 | } 47 | 48 | return Serializable.class == target || Object.class == target || target.isInstance(getObject()); 49 | } 50 | 51 | @SuppressWarnings("unchecked") 52 | @Override 53 | protected T doGetBody(Class asType) throws JMSException { 54 | try { 55 | return (T) getObject(); 56 | } catch (JMSException e) { 57 | throw new MessageFormatException("Failed to read Object: " + e.getMessage()); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSQueue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.Queue; 20 | 21 | /** 22 | * Mock JMS Queue implementation 23 | */ 24 | public class MockJMSQueue extends MockJMSDestination implements Queue { 25 | 26 | public MockJMSQueue() { 27 | super(null, false, false); 28 | } 29 | 30 | public MockJMSQueue(String name) { 31 | super(name, false, false); 32 | } 33 | 34 | /** 35 | * @return name 36 | * @see jakarta.jms.Queue#getQueueName() 37 | */ 38 | @Override 39 | public String getQueueName() { 40 | return getName(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSQueueBrowser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import java.util.Collections; 20 | import java.util.Enumeration; 21 | import java.util.NoSuchElementException; 22 | import java.util.concurrent.atomic.AtomicBoolean; 23 | 24 | import jakarta.jms.IllegalStateException; 25 | import jakarta.jms.JMSException; 26 | import jakarta.jms.Message; 27 | import jakarta.jms.Queue; 28 | import jakarta.jms.QueueBrowser; 29 | 30 | /** 31 | * Mock JMS QueueBrowser implementation. 32 | */ 33 | public class MockJMSQueueBrowser implements QueueBrowser, AutoCloseable, Enumeration { 34 | 35 | private final AtomicBoolean closed = new AtomicBoolean(); 36 | 37 | @SuppressWarnings("unused") 38 | private final MockJMSSession session; 39 | private final String browserId; 40 | private final String messageSelector; 41 | private final MockJMSDestination queue; 42 | 43 | public MockJMSQueueBrowser(MockJMSSession session, String browserId, MockJMSDestination queue, String messageSelector) { 44 | this.session = session; 45 | this.browserId = browserId; 46 | this.queue = queue; 47 | this.messageSelector = messageSelector; 48 | } 49 | 50 | @Override 51 | public void close() throws JMSException { 52 | if (closed.compareAndSet(false, true)) { 53 | 54 | } 55 | } 56 | 57 | @Override 58 | public Enumeration getEnumeration() throws JMSException { 59 | checkClosed(); 60 | return Collections.emptyEnumeration(); 61 | } 62 | 63 | @Override 64 | public boolean hasMoreElements() { 65 | return false; 66 | } 67 | 68 | @Override 69 | public Message nextElement() { 70 | throw new NoSuchElementException(); 71 | } 72 | 73 | //----- Browser Configuration --------------------------------------------// 74 | 75 | @Override 76 | public Queue getQueue() throws JMSException { 77 | checkClosed(); 78 | return (Queue) queue; 79 | } 80 | 81 | @Override 82 | public String getMessageSelector() throws JMSException { 83 | checkClosed(); 84 | return messageSelector; 85 | } 86 | 87 | public String getBrowserId() { 88 | return browserId; 89 | } 90 | 91 | //----- Internal Support Methods -----------------------------------------// 92 | 93 | protected void checkClosed() throws IllegalStateException { 94 | if (closed.get()) { 95 | throw new IllegalStateException("The QueueBrowser is closed"); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSQueueReceiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.IllegalStateException; 20 | import jakarta.jms.JMSException; 21 | import jakarta.jms.Queue; 22 | import jakarta.jms.QueueReceiver; 23 | 24 | /** 25 | * Mock Implementation of a JMS QueueReceiver 26 | */ 27 | public class MockJMSQueueReceiver extends MockJMSMessageConsumer implements AutoCloseable, QueueReceiver { 28 | 29 | protected MockJMSQueueReceiver(MockJMSSession session, String consumerId, MockJMSDestination destination, String messageSelector) throws JMSException { 30 | super(session, consumerId, destination, messageSelector, false); 31 | } 32 | 33 | @Override 34 | public Queue getQueue() throws IllegalStateException { 35 | checkClosed(); 36 | return (Queue) this.destination; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSQueueSender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.IllegalStateException; 20 | import jakarta.jms.JMSException; 21 | import jakarta.jms.Message; 22 | import jakarta.jms.Queue; 23 | import jakarta.jms.QueueSender; 24 | 25 | /** 26 | * Mock JMS QueueSender implementation. 27 | */ 28 | public class MockJMSQueueSender extends MockJMSMessageProducer implements QueueSender, AutoCloseable { 29 | 30 | public MockJMSQueueSender(MockJMSSession session, String producerId, MockJMSDestination destination) throws JMSException { 31 | super(session, producerId, destination); 32 | } 33 | 34 | @Override 35 | public Queue getQueue() throws IllegalStateException { 36 | checkClosed(); 37 | return (Queue) this.destination; 38 | } 39 | 40 | @Override 41 | public void send(Queue queue, Message message) throws JMSException { 42 | super.send(queue, message); 43 | } 44 | 45 | @Override 46 | public void send(Queue queue, Message message, int deliveryMode, int priority, long timeToLive) throws JMSException { 47 | super.send(queue, message, deliveryMode, priority, timeToLive); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSQueueSession.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.Destination; 20 | import jakarta.jms.JMSException; 21 | import jakarta.jms.MessageConsumer; 22 | import jakarta.jms.MessageProducer; 23 | import jakarta.jms.QueueSession; 24 | import jakarta.jms.TemporaryTopic; 25 | import jakarta.jms.Topic; 26 | import jakarta.jms.TopicPublisher; 27 | import jakarta.jms.TopicSubscriber; 28 | 29 | /** 30 | * Mock JMS Queue Session 31 | */ 32 | public class MockJMSQueueSession extends MockJMSSession implements QueueSession, AutoCloseable { 33 | 34 | public MockJMSQueueSession(String sessionId, int sessionMode, MockJMSConnection connection) { 35 | super(sessionId, sessionMode, connection); 36 | } 37 | 38 | @Override 39 | public MessageConsumer createConsumer(Destination destination) throws JMSException { 40 | if (destination instanceof Topic) { 41 | throw new IllegalStateException("Operation not supported by a QueueSession"); 42 | } 43 | return super.createConsumer(destination); 44 | } 45 | 46 | @Override 47 | public MessageConsumer createConsumer(Destination destination, String messageSelector) throws JMSException { 48 | if (destination instanceof Topic) { 49 | throw new IllegalStateException("Operation not supported by a QueueSession"); 50 | } 51 | return super.createConsumer(destination, messageSelector); 52 | } 53 | 54 | @Override 55 | public MessageConsumer createConsumer(Destination destination, String messageSelector, boolean noLocal) throws JMSException { 56 | if (destination instanceof Topic) { 57 | throw new IllegalStateException("Operation not supported by a QueueSession"); 58 | } 59 | return super.createConsumer(destination, messageSelector, noLocal); 60 | } 61 | 62 | @Override 63 | public TopicSubscriber createDurableSubscriber(Topic topic, String name) throws JMSException { 64 | throw new IllegalStateException("Operation not supported by a QueueSession"); 65 | } 66 | 67 | @Override 68 | public TopicSubscriber createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal) throws JMSException { 69 | throw new IllegalStateException("Operation not supported by a QueueSession"); 70 | } 71 | 72 | @Override 73 | public MessageProducer createProducer(Destination destination) throws JMSException { 74 | if (destination instanceof Topic) { 75 | throw new IllegalStateException("Operation not supported by a QueueSession"); 76 | } 77 | return super.createProducer(destination); 78 | } 79 | 80 | @Override 81 | public TemporaryTopic createTemporaryTopic() throws JMSException { 82 | throw new IllegalStateException("Operation not supported by a QueueSession"); 83 | } 84 | 85 | @Override 86 | public Topic createTopic(String topicName) throws JMSException { 87 | throw new IllegalStateException("Operation not supported by a QueueSession"); 88 | } 89 | 90 | @Override 91 | public void unsubscribe(String name) throws JMSException { 92 | throw new IllegalStateException("Operation not supported by a QueueSession"); 93 | } 94 | 95 | @Override 96 | public TopicPublisher createPublisher(Topic topic) throws JMSException { 97 | throw new IllegalStateException("Operation not supported by a QueueSession"); 98 | } 99 | 100 | @Override 101 | public TopicSubscriber createSubscriber(Topic topic) throws JMSException { 102 | throw new IllegalStateException("Operation not supported by a QueueSession"); 103 | } 104 | 105 | @Override 106 | public TopicSubscriber createSubscriber(Topic topic, String messageSelector, boolean noLocal) throws JMSException { 107 | throw new IllegalStateException("Operation not supported by a QueueSession"); 108 | } 109 | 110 | @Override 111 | public MessageConsumer createSharedConsumer(Topic topic, String name) throws JMSException { 112 | throw new IllegalStateException("Operation not supported by a QueueSession"); 113 | } 114 | 115 | @Override 116 | public MessageConsumer createSharedConsumer(Topic topic, String name, String selector) throws JMSException { 117 | throw new IllegalStateException("Operation not supported by a QueueSession"); 118 | } 119 | 120 | @Override 121 | public MessageConsumer createSharedDurableConsumer(Topic topic, String name) throws JMSException { 122 | throw new IllegalStateException("Operation not supported by a QueueSession"); 123 | } 124 | 125 | @Override 126 | public MessageConsumer createSharedDurableConsumer(Topic topic, String name, String selector) throws JMSException { 127 | throw new IllegalStateException("Operation not supported by a QueueSession"); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSSessionListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.JMSException; 20 | 21 | /** 22 | * Listener on events from the MockJMSSession 23 | */ 24 | public interface MockJMSSessionListener { 25 | 26 | void onSessionCommit(MockJMSSession session) throws JMSException; 27 | 28 | void onSessionRollback(MockJMSSession session) throws JMSException; 29 | 30 | void onSessionClosed(MockJMSSession session) throws JMSException; 31 | 32 | void onConsumerClose(MockJMSSession session, MockJMSMessageConsumer consumer) throws JMSException; 33 | 34 | void onProducerClose(MockJMSSession session, MockJMSMessageProducer producer) throws JMSException; 35 | 36 | } 37 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSStreamMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | import jakarta.jms.JMSException; 23 | import jakarta.jms.StreamMessage; 24 | 25 | /** 26 | * Mock JMS StreamMessage implementation. 27 | */ 28 | @SuppressWarnings("unused") 29 | public class MockJMSStreamMessage extends MockJMSMessage implements StreamMessage { 30 | 31 | private static final int NO_BYTES_IN_FLIGHT = -1; 32 | 33 | private final List stream = new ArrayList(); 34 | 35 | private int index = -1; 36 | private byte[] bytes; 37 | private int remainingBytes = NO_BYTES_IN_FLIGHT; 38 | 39 | @Override 40 | public boolean readBoolean() throws JMSException { 41 | // TODO Auto-generated method stub 42 | return false; 43 | } 44 | 45 | @Override 46 | public byte readByte() throws JMSException { 47 | // TODO Auto-generated method stub 48 | return 0; 49 | } 50 | 51 | @Override 52 | public short readShort() throws JMSException { 53 | // TODO Auto-generated method stub 54 | return 0; 55 | } 56 | 57 | @Override 58 | public char readChar() throws JMSException { 59 | // TODO Auto-generated method stub 60 | return 0; 61 | } 62 | 63 | @Override 64 | public int readInt() throws JMSException { 65 | // TODO Auto-generated method stub 66 | return 0; 67 | } 68 | 69 | @Override 70 | public long readLong() throws JMSException { 71 | // TODO Auto-generated method stub 72 | return 0; 73 | } 74 | 75 | @Override 76 | public float readFloat() throws JMSException { 77 | // TODO Auto-generated method stub 78 | return 0; 79 | } 80 | 81 | @Override 82 | public double readDouble() throws JMSException { 83 | // TODO Auto-generated method stub 84 | return 0; 85 | } 86 | 87 | @Override 88 | public String readString() throws JMSException { 89 | // TODO Auto-generated method stub 90 | return null; 91 | } 92 | 93 | @Override 94 | public int readBytes(byte[] value) throws JMSException { 95 | // TODO Auto-generated method stub 96 | return 0; 97 | } 98 | 99 | @Override 100 | public Object readObject() throws JMSException { 101 | // TODO Auto-generated method stub 102 | return null; 103 | } 104 | 105 | @Override 106 | public void writeBoolean(boolean value) throws JMSException { 107 | // TODO Auto-generated method stub 108 | } 109 | 110 | @Override 111 | public void writeByte(byte value) throws JMSException { 112 | // TODO Auto-generated method stub 113 | } 114 | 115 | @Override 116 | public void writeShort(short value) throws JMSException { 117 | // TODO Auto-generated method stub 118 | } 119 | 120 | @Override 121 | public void writeChar(char value) throws JMSException { 122 | // TODO Auto-generated method stub 123 | } 124 | 125 | @Override 126 | public void writeInt(int value) throws JMSException { 127 | // TODO Auto-generated method stub 128 | } 129 | 130 | @Override 131 | public void writeLong(long value) throws JMSException { 132 | // TODO Auto-generated method stub 133 | } 134 | 135 | @Override 136 | public void writeFloat(float value) throws JMSException { 137 | // TODO Auto-generated method stub 138 | } 139 | 140 | @Override 141 | public void writeDouble(double value) throws JMSException { 142 | // TODO Auto-generated method stub 143 | } 144 | 145 | @Override 146 | public void writeString(String value) throws JMSException { 147 | // TODO Auto-generated method stub 148 | } 149 | 150 | @Override 151 | public void writeBytes(byte[] value) throws JMSException { 152 | // TODO Auto-generated method stub 153 | } 154 | 155 | @Override 156 | public void writeBytes(byte[] value, int offset, int length) throws JMSException { 157 | // TODO Auto-generated method stub 158 | } 159 | 160 | @Override 161 | public void writeObject(Object value) throws JMSException { 162 | // TODO Auto-generated method stub 163 | } 164 | 165 | @Override 166 | public void clearBody() { 167 | stream.clear(); 168 | index = -1; 169 | } 170 | 171 | @Override 172 | public void reset() throws JMSException { 173 | index = -1; 174 | } 175 | 176 | @Override 177 | public boolean isBodyAssignableTo(@SuppressWarnings("rawtypes") Class target) throws JMSException { 178 | return false; 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSTemporaryDestination.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.JMSException; 20 | 21 | /** 22 | * Temporary Destination Object 23 | */ 24 | public abstract class MockJMSTemporaryDestination extends MockJMSDestination { 25 | 26 | private boolean deleted; 27 | 28 | public MockJMSTemporaryDestination() { 29 | this(null, false); 30 | } 31 | 32 | public MockJMSTemporaryDestination(String name, boolean topic) { 33 | super(name, topic, true); 34 | } 35 | 36 | void setConnection(MockJMSConnection connection) { 37 | this.connection = connection; 38 | } 39 | 40 | MockJMSConnection getConnection() { 41 | return this.connection; 42 | } 43 | 44 | /** 45 | * Attempts to delete the destination if there is an assigned Connection object. 46 | * 47 | * @throws JMSException if an error occurs or the provider doesn't support 48 | * delete of destinations from the client. 49 | */ 50 | protected void tryDelete() throws JMSException { 51 | if (connection != null) { 52 | connection.deleteTemporaryDestination(this); 53 | } 54 | 55 | deleted = true; 56 | } 57 | 58 | protected boolean isDeleted() throws JMSException { 59 | boolean result = deleted; 60 | 61 | if (!result && connection != null) { 62 | result = connection.isTemporaryDestinationDeleted(this); 63 | } 64 | 65 | return result; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSTemporaryQueue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.JMSException; 20 | import jakarta.jms.TemporaryQueue; 21 | 22 | /** 23 | * Temporary Queue Object 24 | */ 25 | public class MockJMSTemporaryQueue extends MockJMSTemporaryDestination implements TemporaryQueue { 26 | 27 | public MockJMSTemporaryQueue() { 28 | this(null); 29 | } 30 | 31 | public MockJMSTemporaryQueue(String name) { 32 | super(name, false); 33 | } 34 | 35 | /** 36 | * @see jakarta.jms.TemporaryQueue#delete() 37 | */ 38 | @Override 39 | public void delete() throws JMSException { 40 | tryDelete(); 41 | } 42 | 43 | /** 44 | * @return name 45 | * @see jakarta.jms.Queue#getQueueName() 46 | */ 47 | @Override 48 | public String getQueueName() { 49 | return getName(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSTemporaryTopic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.JMSException; 20 | import jakarta.jms.TemporaryTopic; 21 | 22 | /** 23 | * Temporary Topic Object 24 | */ 25 | public class MockJMSTemporaryTopic extends MockJMSTemporaryDestination implements TemporaryTopic { 26 | 27 | public MockJMSTemporaryTopic() { 28 | this(null); 29 | } 30 | 31 | public MockJMSTemporaryTopic(String name) { 32 | super(name, true); 33 | } 34 | 35 | /** 36 | * @see jakarta.jms.TemporaryTopic#delete() 37 | */ 38 | @Override 39 | public void delete() throws JMSException { 40 | tryDelete(); 41 | } 42 | 43 | /** 44 | * @return name 45 | * @see jakarta.jms.Topic#getTopicName() 46 | */ 47 | @Override 48 | public String getTopicName() { 49 | return getName(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSTextMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.JMSException; 20 | import jakarta.jms.TextMessage; 21 | 22 | /** 23 | * Mock JMS TextMessage implementation. 24 | */ 25 | @SuppressWarnings("unchecked") 26 | public class MockJMSTextMessage extends MockJMSMessage implements TextMessage { 27 | 28 | private String text; 29 | 30 | @Override 31 | public void setText(String text) throws JMSException { 32 | this.text = text; 33 | } 34 | 35 | @Override 36 | public String getText() throws JMSException { 37 | return text; 38 | } 39 | 40 | @Override 41 | public boolean isBodyAssignableTo(@SuppressWarnings("rawtypes") Class target) throws JMSException { 42 | return text != null ? target.isAssignableFrom(String.class) : true; 43 | } 44 | 45 | @Override 46 | protected T doGetBody(Class asType) throws JMSException { 47 | return (T) getText(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSTopic.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.Topic; 20 | 21 | /** 22 | * Mock JMS Topic object. 23 | */ 24 | public class MockJMSTopic extends MockJMSDestination implements Topic { 25 | 26 | public MockJMSTopic() { 27 | this(null); 28 | } 29 | 30 | public MockJMSTopic(String name) { 31 | super(name, true, false); 32 | } 33 | 34 | /** 35 | * @return the name 36 | * @see jakarta.jms.Topic#getTopicName() 37 | */ 38 | @Override 39 | public String getTopicName() { 40 | return getName(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSTopicPublisher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.IllegalStateException; 20 | import jakarta.jms.JMSException; 21 | import jakarta.jms.Message; 22 | import jakarta.jms.Topic; 23 | import jakarta.jms.TopicPublisher; 24 | 25 | /** 26 | * Mock JMS TopicPublisher implementation. 27 | */ 28 | public class MockJMSTopicPublisher extends MockJMSMessageProducer implements AutoCloseable, TopicPublisher { 29 | 30 | public MockJMSTopicPublisher(MockJMSSession session, String producerId, MockJMSDestination destination) throws JMSException { 31 | super(session, producerId, destination); 32 | } 33 | 34 | @Override 35 | public Topic getTopic() throws IllegalStateException { 36 | checkClosed(); 37 | return (Topic) this.destination; 38 | } 39 | 40 | @Override 41 | public void publish(Message message) throws JMSException { 42 | super.send(message); 43 | } 44 | 45 | @Override 46 | public void publish(Topic topic, Message message) throws JMSException { 47 | super.send(topic, message); 48 | } 49 | 50 | @Override 51 | public void publish(Message message, int deliveryMode, int priority, long timeToLive) throws JMSException { 52 | super.send(message, deliveryMode, priority, timeToLive); 53 | } 54 | 55 | @Override 56 | public void publish(Topic topic, Message message, int deliveryMode, int priority, long timeToLive) throws JMSException { 57 | super.send(topic, message, deliveryMode, priority, timeToLive); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSTopicSession.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.Destination; 20 | import jakarta.jms.IllegalStateException; 21 | import jakarta.jms.JMSException; 22 | import jakarta.jms.MessageConsumer; 23 | import jakarta.jms.MessageProducer; 24 | import jakarta.jms.Queue; 25 | import jakarta.jms.QueueBrowser; 26 | import jakarta.jms.QueueReceiver; 27 | import jakarta.jms.QueueSender; 28 | import jakarta.jms.TemporaryQueue; 29 | import jakarta.jms.TopicSession; 30 | 31 | /** 32 | * Mock JMS TopicSession 33 | */ 34 | public class MockJMSTopicSession extends MockJMSSession implements TopicSession, AutoCloseable { 35 | 36 | public MockJMSTopicSession(String sessionId, int sessionMode, MockJMSConnection connection) { 37 | super(sessionId, sessionMode, connection); 38 | } 39 | 40 | /** 41 | * @see jakarta.jms.Session#createBrowser(jakarta.jms.Queue) 42 | */ 43 | @Override 44 | public QueueBrowser createBrowser(Queue queue) throws JMSException { 45 | throw new IllegalStateException("Operation not supported by a TopicSession"); 46 | } 47 | 48 | /** 49 | * @see jakarta.jms.Session#createBrowser(jakarta.jms.Queue, java.lang.String) 50 | */ 51 | @Override 52 | public QueueBrowser createBrowser(Queue queue, String messageSelector) throws JMSException { 53 | throw new IllegalStateException("Operation not supported by a TopicSession"); 54 | } 55 | 56 | /** 57 | * @see jakarta.jms.Session#createConsumer(jakarta.jms.Destination) 58 | */ 59 | @Override 60 | public MessageConsumer createConsumer(Destination destination) throws JMSException { 61 | if (destination instanceof Queue) { 62 | throw new IllegalStateException("Operation not supported by a TopicSession"); 63 | } 64 | return super.createConsumer(destination); 65 | } 66 | 67 | /** 68 | * @see jakarta.jms.Session#createConsumer(jakarta.jms.Destination, java.lang.String) 69 | */ 70 | @Override 71 | public MessageConsumer createConsumer(Destination destination, String messageSelector) throws JMSException { 72 | if (destination instanceof Queue) { 73 | throw new IllegalStateException("Operation not supported by a TopicSession"); 74 | } 75 | return super.createConsumer(destination, messageSelector); 76 | } 77 | 78 | /** 79 | * @see jakarta.jms.Session#createConsumer(jakarta.jms.Destination, java.lang.String) 80 | */ 81 | @Override 82 | public MessageConsumer createConsumer(Destination destination, String messageSelector, boolean noLocal) throws JMSException { 83 | if (destination instanceof Queue) { 84 | throw new IllegalStateException("Operation not supported by a TopicSession"); 85 | } 86 | return super.createConsumer(destination, messageSelector, noLocal); 87 | } 88 | 89 | /** 90 | * @see jakarta.jms.Session#createProducer(jakarta.jms.Destination) 91 | */ 92 | @Override 93 | public MessageProducer createProducer(Destination destination) throws JMSException { 94 | if (destination instanceof Queue) { 95 | throw new IllegalStateException("Operation not supported by a TopicSession"); 96 | } 97 | return super.createProducer(destination); 98 | } 99 | 100 | /** 101 | * @see jakarta.jms.Session#createQueue(java.lang.String) 102 | */ 103 | @Override 104 | public Queue createQueue(String queueName) throws JMSException { 105 | throw new IllegalStateException("Operation not supported by a TopicSession"); 106 | } 107 | 108 | /** 109 | * @see jakarta.jms.Session#createTemporaryQueue() 110 | */ 111 | @Override 112 | public TemporaryQueue createTemporaryQueue() throws JMSException { 113 | throw new IllegalStateException("Operation not supported by a TopicSession"); 114 | } 115 | 116 | /** 117 | * @see jakarta.jms.QueueSession#createReceiver(jakarta.jms.Queue) 118 | */ 119 | @Override 120 | public QueueReceiver createReceiver(Queue queue) throws JMSException { 121 | throw new IllegalStateException("Operation not supported by a TopicSession"); 122 | } 123 | 124 | /** 125 | * @see jakarta.jms.QueueSession#createReceiver(jakarta.jms.Queue, java.lang.String) 126 | */ 127 | @Override 128 | public QueueReceiver createReceiver(Queue queue, String messageSelector) throws JMSException { 129 | throw new IllegalStateException("Operation not supported by a TopicSession"); 130 | } 131 | 132 | /** 133 | * @see jakarta.jms.QueueSession#createSender(jakarta.jms.Queue) 134 | */ 135 | @Override 136 | public QueueSender createSender(Queue queue) throws JMSException { 137 | throw new IllegalStateException("Operation not supported by a TopicSession"); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSTopicSubscriber.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.IllegalStateException; 20 | import jakarta.jms.JMSException; 21 | import jakarta.jms.Topic; 22 | import jakarta.jms.TopicSubscriber; 23 | 24 | /** 25 | * Implementation of a TopicSubscriber 26 | */ 27 | public class MockJMSTopicSubscriber extends MockJMSMessageConsumer implements TopicSubscriber { 28 | 29 | public MockJMSTopicSubscriber(MockJMSSession session, String consumerId, MockJMSDestination destination, String messageSelector, boolean noLocal) throws JMSException { 30 | super(session, consumerId, destination, messageSelector, noLocal); 31 | } 32 | 33 | @Override 34 | public Topic getTopic() throws IllegalStateException { 35 | checkClosed(); 36 | return (Topic) this.destination; 37 | } 38 | 39 | @Override 40 | public boolean getNoLocal() throws JMSException { 41 | checkClosed(); 42 | return noLocal; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSXAConnection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.JMSException; 20 | import jakarta.jms.QueueSession; 21 | import jakarta.jms.Session; 22 | import jakarta.jms.TopicSession; 23 | import jakarta.jms.XAConnection; 24 | import jakarta.jms.XASession; 25 | 26 | /** 27 | * Simple Mock JMS XAConnection implementation for unit tests 28 | */ 29 | public class MockJMSXAConnection extends MockJMSConnection implements XAConnection { 30 | 31 | public MockJMSXAConnection(MockJMSUser user) { 32 | super(user); 33 | } 34 | 35 | @Override 36 | public QueueSession createQueueSession(boolean transacted, int acknowledgeMode) throws JMSException { 37 | throw new UnsupportedOperationException("Not yet implemented"); 38 | } 39 | 40 | @Override 41 | public TopicSession createTopicSession(boolean transacted, int acknowledgeMode) throws JMSException { 42 | throw new UnsupportedOperationException("Not yet implemented"); 43 | } 44 | 45 | @Override 46 | public Session createSession(boolean transacted, int acknowledgeMode) throws JMSException { 47 | checkClosedOrFailed(); 48 | ensureConnected(); 49 | int ackMode = getSessionAcknowledgeMode(true, Session.SESSION_TRANSACTED); 50 | MockJMSXASession result = new MockJMSXASession(getNextSessionId(), ackMode, this); 51 | addSession(result); 52 | if (isStarted()) { 53 | result.start(); 54 | } 55 | return result; 56 | } 57 | 58 | @Override 59 | public XASession createXASession() throws JMSException { 60 | return (XASession) createSession(true, Session.SESSION_TRANSACTED); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSXAConnectionFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import jakarta.jms.JMSException; 20 | import jakarta.jms.XAConnection; 21 | import jakarta.jms.XAConnectionFactory; 22 | import jakarta.jms.XAJMSContext; 23 | 24 | /** 25 | * A simple mock JMS XA ConnectionFactory implementation for tests 26 | */ 27 | public class MockJMSXAConnectionFactory extends MockJMSConnectionFactory implements XAConnectionFactory { 28 | 29 | @Override 30 | public XAConnection createXAConnection() throws JMSException { 31 | return (XAConnection) super.createConnection(); 32 | } 33 | 34 | @Override 35 | public XAConnection createXAConnection(String userName, String password) throws JMSException { 36 | return (XAConnection) super.createConnection(userName, password); 37 | } 38 | 39 | @Override 40 | public XAJMSContext createXAContext() { 41 | throw new UnsupportedOperationException("Not implemented yet"); 42 | } 43 | 44 | @Override 45 | public XAJMSContext createXAContext(String userName, String password) { 46 | throw new UnsupportedOperationException("Not implemented yet"); 47 | } 48 | 49 | @Override 50 | protected MockJMSConnection createMockConnectionInstance(MockJMSUser user ) { 51 | return new MockJMSXAConnection(user); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/mock/MockJMSXASession.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.mock; 18 | 19 | import javax.transaction.xa.XAResource; 20 | 21 | import jakarta.jms.JMSException; 22 | import jakarta.jms.Session; 23 | import jakarta.jms.XASession; 24 | 25 | /** 26 | * Mock JMS XA Session for use in unit tests 27 | */ 28 | public class MockJMSXASession extends MockJMSSession implements XASession { 29 | 30 | public MockJMSXASession(String sessionId, int sessionMode, MockJMSConnection connection) { 31 | super(sessionId, sessionMode, connection); 32 | } 33 | 34 | @Override 35 | public Session getSession() throws JMSException { 36 | return this; 37 | } 38 | 39 | @Override 40 | public XAResource getXAResource() { 41 | return null; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pooled-jms/src/test/java/org/messaginghub/pooled/jms/util/Wait.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one or more 3 | * contributor license agreements. See the NOTICE file distributed with 4 | * this work for additional information regarding copyright ownership. 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 6 | * (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | package org.messaginghub.pooled.jms.util; 18 | 19 | import java.util.concurrent.TimeUnit; 20 | 21 | public class Wait { 22 | 23 | public static final long MAX_WAIT_MILLIS = 30 * 1000; 24 | public static final long SLEEP_MILLIS = 200; 25 | 26 | public interface Condition { 27 | boolean isSatisfied() throws Exception; 28 | } 29 | 30 | public static boolean waitFor(Condition condition) throws Exception { 31 | return waitFor(condition, MAX_WAIT_MILLIS); 32 | } 33 | 34 | public static boolean waitFor(final Condition condition, final long duration) throws Exception { 35 | return waitFor(condition, duration, SLEEP_MILLIS); 36 | } 37 | 38 | public static boolean waitFor(final Condition condition, final long duration, final long sleepMillis) throws Exception { 39 | 40 | final long expiry = System.currentTimeMillis() + duration; 41 | boolean conditionSatisfied = condition.isSatisfied(); 42 | while (!conditionSatisfied && System.currentTimeMillis() < expiry) { 43 | TimeUnit.MILLISECONDS.sleep(sleepMillis); 44 | conditionSatisfied = condition.isSatisfied(); 45 | } 46 | return conditionSatisfied; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /pooled-jms/src/test/resources/simplelogger.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed to the Apache Software Foundation (ASF) under one 3 | # or more contributor license agreements. See the NOTICE file 4 | # distributed with this work for additional information 5 | # regarding copyright ownership. The ASF licenses this file 6 | # to you under the Apache License, Version 2.0 (the 7 | # "License"); you may not use this file except in compliance 8 | # with the License. You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, 13 | # software distributed under the License is distributed on an 14 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | # KIND, either express or implied. See the License for the 16 | # specific language governing permissions and limitations 17 | # under the License. 18 | # 19 | org.slf4j.simpleLogger.logFile=System.out 20 | 21 | org.slf4j.simpleLogger.defaultLogLevel=trace 22 | 23 | org.slf4j.simpleLogger.showDateTime=true 24 | org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss,SSS 25 | 26 | org.slf4j.simpleLogger.log.org.messaginghub.pooled.jms=DEBUG 27 | 28 | --------------------------------------------------------------------------------