diff options
Diffstat (limited to 'java/jca')
57 files changed, 2974 insertions, 1200 deletions
diff --git a/java/jca/.gitignore b/java/jca/.gitignore deleted file mode 100644 index 1377554ebe..0000000000 --- a/java/jca/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.swp diff --git a/java/jca/README.txt b/java/jca/README.txt index 29e6825c4c..a4d426310d 100644 --- a/java/jca/README.txt +++ b/java/jca/README.txt @@ -5,9 +5,10 @@ Overview The Qpid Resource Adapter is a JCA 1.5 compliant resource adapter that allows for JEE integration between EE applications and AMQP 0.10 message brokers. -The adapter provides both outbound and inbound connectivity and +The Qpid JCA adapter provides both outbound and inbound connectivity and exposes a variety of options to fine tune your messaging applications. Currently -the adapter only supports C++ based brokers and has only been tested with Apache Qpid C++ broker. +the adapter only supports C++ based brokers and has only been tested with Apache +Qpid C++ broker. The following document explains general configuration information for the Qpid JCA RA. Details for specific application server platforms are provided in separate README files typically designated as @@ -31,30 +32,29 @@ When a ManagedConnectionFactory JavaBean or ActivationSpec JavaBean are deployed the configuration properties from the ResourceAdapter or provide specific properties which in turn will override the defaults. -While some of the properties from the three componets are specific to the JCA adapter, a majority of the -properties directly correspond the the Qpid JMS client. As such, it is strongly encouraged your familiarize -yourself with the correct syntax, configuration options for the JMS client as well as the JCA adapter. Similarly, -familiarity with the 1.5 JCA specification is encouraged though not strictly required. +While some of the properties from the three components are specific to the JCA adapter, a majority of the +properties directly correspond the the Qpid JMS client. As such, familiarity with the Qpid JMS Client is strongly +encouraged. Similarly, familiarity with the JCA 1.5 specification is encouraged though not strictly required. The ResourceAdapter JavaBean ============================ -The ResourceAdapter JavaBean provides global configuration options for both inbound and outbound connectivity. -The set of ResourceAdapter properties are described below. The ResourceAdapter properties can be found in the META-INF/ra.xml -deployment descriptor which is provided with the adapter. Note, deploying a ResourceAdapter, ManagedConnectionFactory -or ActivationSpec is application server specific. As such, this document provides an explanation of these properties -but not how they are configured as this is environment specific. +The ResourceAdapter JavaBean provides global configuration options for both inbound and outbound +connectivity. The set of ResourceAdapter properties are described below. The ResourceAdapter properties +can be found in the META-INF/ra.xml deployment descriptor which is provided with the adapter. Note, +deploying a ResourceAdapter, ManagedConnectionFactory or ActivationSpec is application server specific. +As such, this document provides an explanation of these properties but not how they are configured. ResourceAdapter JavaBean Properties =================================== -ClientID +ClientId The unique client identifier. From the JMS API this is used only in the context of durable subscriptions. Default: client_id SetupAttempts - The number of attempts the ResourceAdapter will make to successfully setup an inbound activation on deployment, or when an exception - occurs at runtime. + The number of attempts the ResourceAdapter will make to successfully setup an inbound activation on deployment, + or when an exception occurs at runtime. Default: 5 SetupInterval @@ -65,14 +65,6 @@ UseLocalTx Whether or not to use local transactions instead of XA. Default: false -DefaultUserName - The default user name to use. -Default: guest - -DefaultPassword - The default password to use. -Default: guest - Host The hostname/ip address of the broker. Default: localhost @@ -87,23 +79,25 @@ Default: test ConnectionURL The full connection URL to the broker. -Default:amqp://guest:guest@/test?brokerlist='tcp://localhost:5672' +Default: amqp://anonymous:passwd@client/test?brokerlist='tcp://localhost?sasl_mechs='PLAIN'' TransactionManagerLocatorClass - The class responsible for locating the transaction manager within a specific application server. This is a ResourceAdapter - Java Bean specific property and is application server specific. As such, it is currently commented out. Two examples have - been provided. + The class responsible for locating the transaction manager within a specific application server. + This is a ResourceAdapter Java Bean specific property and is application server specific, as such, + no default is provided. Default: none TransactionManagerLocatorMethod - The specific method on the class above used to acquire a reference to the platform specific transaction manager. - This is a ResourceAdapter Java Bean specific property and is application server specific. - As such, it is currently commented out. Two examples have been provided. + The specific method on the TransactionManagerLocatorClass used to acquire a reference to the platform + specific transaction manager. This is a ResourceAdapter Java Bean specific property and is application + server specific as such, no default is provided. Default:none -Note, if you require XA support, both the TransactionManagerLocatorClass and the TransactionManagerLocatorMethod -properties MUST be set. While application servers typically provide a mechanism to do this in the form of a specific -deployment descriptor, or GUI console, the ra.xml file can also be modified directly. +UseConnectionPerHandler + The Apache C++ Broker multiplexes on the physical connection rather than the session. As a result, performance + improvements can be gained by allocating and assigning a connection per inbound listener. The alternative is + to share a connection across each handler for a given endpoint (MDB). +Default:true The ManagedConnectionFactory JavaBean ===================================== @@ -112,28 +106,16 @@ The ManagedConnectionFactory JavaBean provides outbound connectivity for the Qpi inherited from the ResourceAdapter JavaBean, the ManagedConnectionFactory JavaBean provides specific properties only applicable to outbound connectivity. -sessionDefaulType +SessionDefaulType The default type of Session. Currently unused. Default: java.jms.Queue -useTryLock +UseTryLock Multi-purpose property used to specify both that a lock on the underlying managed connection should be used, as well as the wait duration to aquire the lock. Primarily used for transaction management. A null or zero value will atttempt to acquire the lock without a duration. Anything greater than zero will wait n number of seconds before failing to acquire the lock. Default:0 -KeyStorePassword - The KeyStore password for SSL -Default:none - -KeyStorePath - The path to the KeyStore. -Default:none - -CertType - The type of certificate. -Default:SunX509 - The ActivationSpec JavaBean =========================== The ActivationSpec JavaBean provides inbound connectivity for the Qpid JCA adapter. In addition to most of the properties @@ -149,7 +131,7 @@ UseJNDI Default: true Destination - The name of the destination on which to listen for messages. + The JNDI name of the destination on which to listen for messages. Default:none DestinationType @@ -187,49 +169,56 @@ PrefetchLow PrefetchHigh Qpid specific -- TODO more explanation - +Setup Administered Objects ====================== The JCA specification provides for administered objects. Ass per the specification, administered objects are -JavaBeans that specific to the messaging provider. The Qpid JCA Resource Adapter provides two administered +JavaBeans that specific to the messaging provider. The Qpid JCA Resource Adapter provides three administered objects that can be used to configure JMS destinations and a specialized JMS Connection Factory respectively. Both these administered objects have properities to support configuration and deployment. -QpidDestinationProxy +QpidQueue/QpidTopic ==================== - The QpidDestinationProxy allows a developer, deployer or adminstrator to create destinations (queues or topic) and - bind these destinations into JNDI. The following lists the properties applicable to the QpidDestinationProxy +The QpidQueue and QpidTopic AdminObjects allow binding JMS destintations into the JEE JNDI namespace. Both +objects support one property: + +DestinationAddress + The address string of the destination. Please see the Qpid JMS client documentation for valid values. -destinationType - The type of destination to create. Valid values are QUEUE or TOPIC. +Example: + DestinationAddress=hello.Queue;{create:always, node:{type:queue, x-declare:{auto-delete:true}}} + DestinationAddress=amq.topic/hello.Topic + The QpidQueue/QpidTopic AdminObjects allow a developer, deployer or adminstrator to create destinations + (queues or topic) and bind these destinations into JNDI. Only one property is required: -destinationAddress - The address string of the destination. Please see the Qpid Java JMS client documentation for valid values. QpidConnectionFactoryProxy +========================== +The QpidConnectionFactoryProxy allows for a non-JCA ConnectionFactory to be bound into the JNDI tree. This +ConnectionFactory can in turn be used outside of the application server. Typically a ConnectionFactory of +this sort is used by Swing or other non-managed clients not requiring JCA. The QpidConnectionFactoryProxy +provides one property + +ConnectionURL + This is the url used to configure the connection factory. Please see the Qpid JMS client documentation for The QpidConnectionFactoryProxy allows for a non-JCA ConnectionFactory to be bound into the JNDI tree. This ConnectionFactory can in turn be used outside of the application server. Typically a ConnectionFactory of - this sort is used by Swing or other two-tier clients not requiring JCA. The QpidConnectionFactoryProxy provides - one property - -connectionURL - This is the url used to configure the connection factory. Please see the Qpid Java Client documentation for - further details. + this sort is used by Java Swing or other non-managed clients not requiring JCA. One one property is + required: +Example: + amqp://anonymous:passwd@client/test?brokerlist='tcp://localhost:5672?sasl_mechs='PLAIN'' Transaction Support =================== The Qpid JCA Resource Adapter provides three levels of transaction support: XA, LocalTransactions and NoTransaction. Typical usage of the Qpid JCA Resource adapter implies the use of XA transactions, though there are certain scenarios where this is not preferred. Transaction support configuration is application server specific and as such, is explained -in the corresponding documentation for each supported application server. However, there are two limitations with -the Qpid JCA adapter at this time: - -1) Currently, the Qpid C++ broker does not support he use of XA within the context of clustered brokers. As such, if -you are running in a cluster, you will need to configure the adapter to use LocalTransactions. +in the corresponding documentation for each supported application server. -2)XARecovery is currently not implemented. In the case of a system failure, in doubt transactions will have to be -manually resolved by and administrator or otherwise qualified personnel. +XA recovery, that is being able to recover 'in-doubt' transactions for a given resource manager is non-standardized, +and as such is application server specific. Currently, the Qpid JCA adapter only supports recovery for JBoss EAP 5.x +as a separate module. Conclusion ========== diff --git a/java/jca/example/.gitignore b/java/jca/example/.gitignore index 54c810d4a0..624fd61581 100644 --- a/java/jca/example/.gitignore +++ b/java/jca/example/.gitignore @@ -1,3 +1,22 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + build/* lib/* *.swp diff --git a/java/jca/example/README-EXAMPLE.txt b/java/jca/example/README-EXAMPLE.txt new file mode 100644 index 0000000000..3a2ee0c38e --- /dev/null +++ b/java/jca/example/README-EXAMPLE.txt @@ -0,0 +1,235 @@ +Qpid JCA Example + +Overview +======== +The Qpid JCA example provides a sample JEE application that demonstrates how to +configure, install and run applications using the Qpid JCA adapter for JEE +connectivity and the Apache Qpid C++ Broker. This example code can be used as a +convenient starting point for your own development and deployment +efforts. + +Example Components +=================== +Currently the example application consists of the following components: + +Destinations +============ +Any messaging application relies on destinations (queues or topics ) +in order to produce or consume messages.The Qpid JCA example provides +the following destinations: + + HelloTopic + GoodByeTopic + HelloQueue + GoodByeQueue + QpidRequestQueue + QpidResponseQueue + +Each destination is configured for the respective application server in which +the examples will be run. Generally the example application allows for sending +messages to a Hello<DestinationType>. Depending on a configuration option, once +a message is received by the Hello component, the Hello component can also be +sent to a GoodBye<DestinationType> component. + +The QpidRequest/Response destinations provide the destinations for the +request/reponse messaging pattern. + + +ConnectionFactories +=================== +Similar to destinations, ConnectionFactories are a core component of both JMS +and JCA. ConnectionFactories provide the necessary starting point to make a +connection, establish a session and produce or consume (or both) messages from +your JMS provider. + +The Qpid JCA example provides three connection factories by default: + + QpidJMSXA + QpidJMS + QpidConnectionFactory + +Each of these ConnectionFactories varies in their capabilities and the context in which +they should be used. By default, the Qpid JCA examples use the QpidJMSXA connection factory +which provides for full XA transaction support. The QpidJMS connection factory provides a +local JMS transaction CF and is currently deprecated, though it has been maintained for +backwards compatibility. The QpidConnectionFactory is a specialized ConnectionFactory designed +to be used outside of a JEE application server. This CF has been provided to support non-managed +clients that want to use the JNDI facilities of JEE. + +The deployment configuration for destinations, and ConnectionFactories varies by JEE platform. +Please see the application server specific documentation for specific instructions. + +EJB 3.x + +There are a six EJB 3.x components provided as part of the example. + + QpidHelloSubscriberBean - MessageDrivenBean (MDB) + QpidGoodByeSubscriberBean - (MDB) + QpidHelloListenerBean - (MDB) + QpidGoodByeListenerBean - (MDB) + QpidJMSResponderBean - (MDB) + QpidTestBean - Stateless Session Bean (SLSB) + +Generally, the name of the EJB component corresponds to the aforementioned destinations +listed above in the consumption of messages. + +QpidTestServlet +A sample EE 2.5 servlet is provided allowing testing from a browser versus a RMI or JMS +based client. + +QpidTestClient +A Java based client allowing for both RMI or JMS access to the sample application. RMI or +JMS access is based on configuration options. + +QpidRequestResponseClient +A Java based client allowing for a request/response application. + +EE EAR archive + An EAR wrapper for the ejb and web components. + +A build.xml file + An ant build.xml file to configure, install and deploy the aforementioned components. + +Requirements +============ +Apache Qpid Broker +To run the sample it is assumed you have an Apache Qpid C++ broker configured and running. +The example code assumes that the broker will run at localhost on port 5672. The broker +address can be modified in the build-properties.xml file. + +Examples +=============== +Using the Qpid JCA examples is the same regardless of preferred JEE application server. +The provided clients and supported options are listed below. + +QpidTestClient +============== +As previously mentioned, the Qpid JCA example provides an RMI/JMS Java client to test +the application. Executing the command + +ant-run client + +will execute the QpidTestClient client with the default options. + +QpidTestClient Options + +client.use.ejb (build.xml) +Setting this value to false will result in the QpidTestClient using JMS to send messages to +the configured destination. +Default:true + +client.message +The text content of the JMS message sent to the configured destination. +Default: Hello Qpid World! + +client.message.count +The number of messages that will be sent to the configured destionation. +Default: 1 + +client.use.topic +Setting this value to true will send messages to HelloTopic versus HelloQueue. +Default:false + +client.say.goodbye +Setting this value to true will cause the listener on the Hello Queue/Topic to send a +message to the GoodBye Queue/Topic +Default:false + + +QpidRequestResponseClient +========================= +Similar to the QpidTestClient, the QpidRequestResponseClient is a Java based application that allows for +sending messages to a destination. The QpidRequestResponseClient also provides the capability for the +application to listen for a response. Executing the command + +ant run-reqresp + +will run the application with the default options. + +QpidRequestResponseClient Options + +QpidTestServlet +=============== +Similar to the QpidTestClient application, the Qpid JCA examples also provides a JEE Servlet to test and run the +application. This Servlet can be used as an alternative, or in conjunction with the Java application. The Servlet +can be reached via the following URL: + +http://<server-host-name>:<server-port>/qpid-jca-web/qpid + +where server-host and server-port are the host and port where you are running your application server. + +QpidTestServlet Options + +The QpidTestServlet options can be configured by appending certain values to the above URL. These values are +listed below and generally correspond, both in name and purpose, to the Java application configuration options. + +message +The text content of the JMS message sent to the configured destination. +Default: Hello World! + +useEJB +Setting this value to true will result in the QpidTestServlet using the QpidTestBean SLSB to +send the message to the configured destination. By default the QpidTestServlet uses JMS. +Default:false + +count +The number of messages that will be sent to the configured destionation. +Default: 1 + +useTopic +Setting this value to true will send messages to HelloTopic versus HelloQueue. +Default:false + +sayGoodBye +Setting this value to true will cause the listener on the Hello Queue/Topic to send a +message to the GoodBye Queue/Topic +Default:false + +useXA +Setting this value to true will cause the QpidTestServlet to do all activity within the +context of an XA transaction. +Default:false + +useTX +Setting this value to true will cause the QpidTestServlet to do all activity within the +context of a JMS transation. +Default:false + + +Note, the useXA and useTX are mutually exclusive. Setting both to true, the QpidTestServlet +will choose XA over a JMS transaction. + +QpidRequestResponseServlet +========================== +Similar to the QpidRequestResponseClient application, the Qpid JCA examples also provides a JEE Servlet +to execute the request/response type messaging pattern. The Servlet can be reached via the following url: + +http://<server-host-name>:<server-port>/qpid-jca-web/qpid-reqresp + +where server-host and server-port are the host and port where you are running your application server. + +QpidRequestResponseServlet Options + +message +The text content of the JMS message sent to the configured destination. +Default: Hello World! + +count +The number of messages that will be sent to the configured destionation. +Default: 1 + +useXA +Setting this value to true will cause the QpidTestServlet to do all activity within the +context of an XA transaction. +Default:false + +Summary +======= +While conceptually simple, the Qpid JCA examples provide a majority of the component types and messaging patterns +you are most likely to use your development efforts. With the Web and EJB components, you can experiment with +various aspects of JCA as well as EE development in general using the Qpid Broker as your messaging provider. +While this documentation highlights the major components and steps needed to take to get the example running, +the possiblities for modifcation are numerous. You are encouraged to experiment with the example as you work +to develop your own messaging applications. + + diff --git a/java/jca/example/README-GERONIMO.txt b/java/jca/example/README-GERONIMO.txt new file mode 100644 index 0000000000..d58d034c79 --- /dev/null +++ b/java/jca/example/README-GERONIMO.txt @@ -0,0 +1,69 @@ +Qpid JCA Example - Apache Geronimo 2.x + +Overview +======== +This document explains the steps required to configure and +deploy the Qpid JCA examples for the Apache Geronimo environment. +General information can be found in the README.txt file. + +The Apache Geronimo environment provides two methods for deploying +JEE application components: the web-based administration console and the +command line based deployment environment. This document only explains +the command line environment. Please see the Apache Geronimo 2.x +documentation for the web-based console. + +Requirements +============ +In order to deploy the Qpid JCA adapter, as well as the example application, +the GERONIMO_HOME environemnt variable must be set. The environment variable +should point to the root of your Apache Geronimo 2.x install directory. + +In order to automatically deploy the Qpid JCA Adapter, the QPID_JCA_HOME +environment variable needs to be set. The environment variable should point +to the directory which contains the Qpid JCA Adapter. If building from the +source tree, by default this can be found at + +QPID_ROOT/java/build/lib + +If installing from RPM or other binary distribution, this can vary by platform. + +Prior to deploying any application component, the Apache Geronimo application +should be started and available for requests. + + +Deploy the Qpid JCA Adapter +============================== +Once the above requirements are satisfied the command + +ant deploy-rar + +will attempt to use the Apache Geronimo deployer to install the Qpid JCA +adapter into the Apache Geronimo environment. Any errors will be reported +back to the client for further examination. Once the above command executes +successfully, the Qpid JCA adapter has been deployed, configured and is ready +for use. + + +Deploy the Qpid JCA Examples +============================ +After the Qpid JCA adapter is deployed, executing the command + +ant deploy-ear + +will attempt to use the Apache Geronimo deploy to install the Qpid JCA +example EAR into the Apache Geronimo environment. Any errors will be reported +back to the client for further examination. Once the above command executes +successfully, the Qpid JCA example application is deployed, configured and ready +for use. + +The build-geronimo-properties.xml file contain Apache Geronimo specific values +and Ant targets that can be used to suit your development requirements. + +The README.txt file in this directory provides the necessary instructions for using the Qpid JCA +adapter and example application. + + + + + + diff --git a/java/jca/example/README-GLASSFISH.txt b/java/jca/example/README-GLASSFISH.txt new file mode 100644 index 0000000000..1b73ba68fd --- /dev/null +++ b/java/jca/example/README-GLASSFISH.txt @@ -0,0 +1,84 @@ +Qpid JCA Example - Glassfish 3.x + +Overview +======== +This document explains the steps required to configure and +deploy the Qpid JCA examples for the Glassfish 3.x environment. + +The Glassfish environment provides two methods for deploying +JEE application components: the web-based administration console +and the asadmin command line utility. This document only explains +the command line utility. Please see the Glassfish 3.x +documentation for the web-based console approach. + +Requirements +============ +In order to deploy the Qpid JCA adapter, as well as the example application, +the GLASSFISH_HOME environemnt variable must be set. The environment variable +should point to the root of your Glassfish installation. + +In order to automatically deploy the Qpid JCA Adapter from the build system, +the QPID_JCA_HOME environment variable needs to be set. +The environment variable should point to the directory which contains the +Qpid JCA Adapter. If building from the source tree, by default this can be found at + +QPID_ROOT/java/build/lib + +If installing from RPM or other binary distribution, this can vary by OS platform. + +The Qpid JCA examples assume the Apache Geronimo application server as the default +target platform. This can be modified in two ways: + +1) Modify the build.xml file and change the target.platform property: + +Example: + + <!-- Valid target platforms are currently geronimo, jboss, jboss7, glassfish --> + <property name="target.platform" value="glassfish"/> + +2) Set the target.platform property via the command line: + +Example: + +ant -Dtarget.platform=glassfish <target> + +Note, if you choose the second method, all command line invocations must include +the target.platform variable. For the remainder of this document, we will assume +the second approach. + +Prior to deploying any application component, the Glassfish application server +should be started and available for requests. + + +Deploy and configure the Qpid JCA Adapter +============================== +Once the above requirements are satisfied the command + +ant -Dtarget.platform=glassfish deploy-rar + +will attempt to invoke the asadmin utility to deploy and configure the +Qpid JCA adapter. Once this step completes succesfully the Qpid JCA adapter +is deployed, configured and ready for use. + + +Deploy the Qpid JCA Examples +============================ +After the Qpid JCA adapter is deployed, executing the command + +ant -Dtarget.platform=glassfish deploy-ear + +will attempt to deploy the Qpid JCA example EAR into the Glassfish environment. +Once the above command executes successfully, the Qpid JCA example application +is deployed, configured and ready for use. + +The build-glassfish-properties.xml file contains Glassfish specific configuration options +and Ant targets that can be used to suit your development requirements. Executing + +ant -Dtarget.platform=glassfish -p + +will list the appropriate targets and provide a simple description for each. + +The README.txt file in this directory provides the necessary instructions for using +the Qpid JCA adapter and example application which is consistent across all supported +JEE platforms. + diff --git a/java/jca/example/README-JBOSS.txt b/java/jca/example/README-JBOSS.txt new file mode 100644 index 0000000000..e23b3ba308 --- /dev/null +++ b/java/jca/example/README-JBOSS.txt @@ -0,0 +1,107 @@ +Qpid JCA Example - JBoss EAP 5.x, JBoss 5.x, 6.x + +Overview +======== +This document explains the steps required to configure and +deploy the Qpid JCA examples for both the JBoss EAP 5.x +environment as well as the JBoss 5.x/6.x community edition +(herafter simply referred to as JBoss). General information +can be found in the README.txt file. + +Requirements +============ +In order to deploy the Qpid JCA adapter, as well as the example application, +the JBOSS_HOME environemnt variable must be set. The environment variable +should point to the root of your JBoss installation. + +In order to automatically deploy the Qpid JCA Adapter from the build system, +the QPID_JCA_HOME environment variable needs to be set. +The environment variable should point to the directory which contains the +Qpid JCA Adapter. If building from the source tree, by default this can be found at + +QPID_ROOT/java/build/lib + +If installing from RPM or other binary distribution, this can vary by platform. + +If you do not want to use the build system to deploy the Qpid JCA adapter, you +can simply copy the qpid-ra-0.<version>.rar file to the + +JBOSS_HOME/server/<server-name>/deploy + +directory. By default, the example assumes the JBoss 'default' server profile will +be used. This can be modified in the build-jboss-properties.xml file. + +The Qpid JCA examples assume the Apache Geronimo application server as the default +target platform. This can be modified in two ways: + +1) Modify the build.xml file and change the target.platform property: + +Example: + + <!-- Valid target platforms are currently geronimo, jboss, jboss7, glassfish --> + <property name="target.platform" value="jboss"/> + +2) Set the target.platform property via the command line: + +Example: + +ant -Dtarget.platform=jboss <target> + +Note, if you choose the second method, all command line invocations must include +the target.platform. For the remainder of this document, we will assume the second +approach. + +Prior to deploying any application component, the JBoss application server +should be started and available for requests. + + + + +Deploy and configure the Qpid JCA Adapter +============================== +Once the above requirements are satisfied the command + +ant -Dtarget.platform= jboss deploy-rar + +will copy the Qpid JCA adapter to JBoss server deploy directory. + +To configure JCA resources in the JBoss environment, the *-ds.xml configuration file +is used. The command + +ant -Dtarget.platform=jboss deploy-ds + +will accomplish this task using the defaults provided. Any errors will be reported +in the + +JBOSS_HOME/server/<server-name>/log/server.log + +file or on the console. + +Once the above commands execute successfully, the Qpid JCA adapter is deployed, configured +and ready for use. + + +Deploy the Qpid JCA Examples +============================ +After the Qpid JCA adapter is deployed, executing the command + +ant -Dtarget.platform=jboss deploy-ear + +will attempt to deploy the Qpid JCA example EAR into the JBoss environment. +Once the above command executes successfully, the Qpid JCA example application is deployed, +configured and ready for use. + +Note, if making modifications to either the Qpid JCA adapter or *-ds.xml configuration, the +EAR archive will need to be redeployed. This is a JBoss JCA issue and not due to the Qpid JCA +adapter. + +The build-jboss-properties.xml file contains JBoss specific configuration options +and Ant targets that can be used to suit your development requirements. + +The README.txt file in this directory provides the necessary instructions for using the Qpid JCA +adapter and example application which is consistent across all supported JEE platforms. + + + + + diff --git a/java/jca/example/README-JBOSS7.txt b/java/jca/example/README-JBOSS7.txt new file mode 100644 index 0000000000..7a3e0db01a --- /dev/null +++ b/java/jca/example/README-JBOSS7.txt @@ -0,0 +1,116 @@ +Qpid JCA Example - JBoss AS 7 + +Overview +======== +This document explains the steps required to configure and +deploy the Qpid JCA examples for the JBoss AS 7 environment. +General information about the example can be found in the +README-EXAMPLE.txt file. + +Requirements +============ +In order to deploy the Qpid JCA adapter, as well as the example application, +the JBOSS_HOME environemnt variable must be set. The environment variable +should point to the root of your JBoss installation. + +In order to automatically deploy the Qpid JCA Adapter from the build system, +the QPID_JCA_HOME environment variable needs to be set. +The environment variable should point to the directory which contains the +Qpid JCA Adapter. If building from the source tree, by default this can be found at + +QPID_ROOT/java/build/lib + +If installing from RPM or other binary distribution, this can vary by platform. + +If you do not want to use the build system to deploy the Qpid JCA adapter, you +can simply copy the qpid-ra-0.<version>.rar file to the + +JBOSS_HOME/<server-profile>/deployments + +directory. By default, the example assumes the JBoss 'standalone' server profile will +be used. This can be modified in the build-jboss7-properties.xml file. + +The Qpid JCA examples assume the Apache Geronimo application server as the default +target platform. This can be modified in two ways: + +1) Modify the build.xml file and change the target.platform property: + +Example: + + <!-- Valid target platforms are currently geronimo, jboss, jboss7, glassfish --> + <property name="target.platform" value="jboss7"/> + +2) Set the target.platform property via the command line: + +Example: + +ant -Dtarget.platform=jboss7 <target> + +Note, if you choose the second method, all command line invocations must include +the target.platform. For the remainder of this document, we will assume the second +approach. + +As opposed to earlier versions of JBoss AS, JBoss AS 7 uses a different approach for +configuring JCA resources. JBoss AS 7 provides support for different server profiles +each configured through an XML based configuration file. In order to configure the +Qpid JCA adapter for the JBoss AS 7 environment, a complete XML configuration has been +provided in the conf/ directory as conf/qpid-standalone.xml. In order to configure this +file execute the following command: + +ant -Dtarget.platform=jboss7 generate + +The result of this command will produce a file build/gen/qpid-standalone.xml file. To +deploy this file copy the file to: + +JBOSS_HOME/standalone/configuration + +directory. + +Prior to deploying any application component, the JBoss application server +should be started and available for requests. In order to use the qpid-standalone.xml +file generated in the previous step, when starting JBoss AS 7 invoke the following: + +./standalone.sh -c qpid-standalone.xml + + +Note, the above method completely replaces the default messaging provider in JBoss AS 7. +Currently there is no way to have two separate messaging providers deployed within the same +server. It assumed that this will be addressed in a later version of JBoss AS 7. + + +Deploy the Qpid JCA Adapter +============================== +Once the above requirements are satisfied the command + +ant -Dtarget.platform=jboss7 deploy-rar + +will copy the Qpid JCA adapter to JBoss AS 7 server deploy directory. + +Once the above commands execute successfully, the Qpid JCA adapter is deployed, configured +and ready for use. + + +Deploy the Qpid JCA Examples +============================ +After the Qpid JCA adapter is deployed, executing the command + +ant -Dtarget.platform=jboss7 deploy-ear + +will attempt to deploy the Qpid JCA example EAR into the JBoss AS 7 environment. +Once the above command executes successfully, the Qpid JCA example application is +deployed, configured and ready for use. + +Note, currently there is an issue with 'hot-deployment' in the JBoss AS 7 environment. +If you need to re-deploy the EAR file, restarting JBoss AS 7 is required. + +The build-jboss7-properties.xml file contains JBoss AS 7 specific configuration options +and Apache Ant targets that can be used to suit your development requirements. + +The README.txt file in this directory provides the necessary instructions for using the Qpid JCA +adapter and example application which is consistent across all supported JEE platforms. + + + + + + diff --git a/java/jca/example/README.txt b/java/jca/example/README.txt deleted file mode 100644 index d94bbfa7e5..0000000000 --- a/java/jca/example/README.txt +++ /dev/null @@ -1,277 +0,0 @@ -Qpid JCA Example - -Overview -======= -The Qpid JCA example provides a sample JEE application that demonstrates how to -configure, install and run applications using the Qpid JCA adapter for EE -connectivity and the Apache Qpid C++ Broker. This example code can be used as a -convenient starting point for your own development and deployment -efforts. Currently the example is supported on JBoss EAP 5.x, JBoss 6.x and -Apache Geronimo 2.x. - -Example Components -=================== -Currently the example application consists of the following components: - -Destinations and ConnectionFactories - -Any messaging application relies on destinations (queues or topics ) -in order to produce or consume messages.The Qpid JCA example provides -five destinations by default: - - HelloTopic - GoodByeTopic - HelloGoodByeTopic - HelloQueue - GoodByeQueue - QpidResponderQueue - - -Similar to destinations, ConnectionFactories are a core component of both JMS -and JCA. ConnectionFactories provide the necessary starting point to make a connection, -establish a session and produce or consume (or both) messages from your JMS provider. - -The Qpid JCA example provides three connection factories by default: - - QpidJMSXA - QpidJMS - QpidConnectionFactory - -Each of these ConnectionFactories varies in their capabilities and the context in which -they should be used. These concepts will be explained later in this document. - -The deployment configuration for destinations, and ConnectionFactories varies by platform. -In JBossEAP, the configuration mechanism is a *-ds.xml file. Geronimo 2.2.x has the notion -of a deployment plan in the form of a geronimo-ra.xml file. - -The Qpid JCA Example provides both a qpid-jca-ds.xml file as well as a geronimo-ra.xml deployment -plan. Both mechanisms provide a reasonable set of defaults to allow you to deploy the Qpid JCA -adapter in either environment and get up and running quickly. - -EJB 3.x - -There are a six EJB 3.x components provided as part of the example. - - QpidHelloSubscriberBean - MessageDrivenBean (MDB) - QpidGoodByeSubscriberBean - (MDB) - QpidHelloListenerBean - (MDB) - QpidGoodByeListenerBean - (MDB) - QpidJMSResponderBean - (MDB) - QpidTestBean - Stateless Session Bean (SLSB) - -Servlet 2.5 - - QpidTestServlet - -A sample EE 2.5 servlet is provided allowing testing from a browser versus a JNDI -client - -EE EAR archive - An EAR wrapper for the ejb and web components. - - - An RMI client used to excercise the EJB 3.x component. - -Sample *-ds.xml file - A sample *-ds.xml file is provided to create destinations and ManagedConnectionFactories - in the JBoss environment. - -Sample geronimo-ra.xml - A sample geronimo-ra.xml file is provided to create destinations and ManagedConnectionFactories - in the Geronimo environment. This file is semantically equivalent to the JBoss *-ds.xml artifact. - -A build.xml file - An ant build.xml file to configure, install and deploy the aforementioned components. - - -Requirements -============ - -Depending upon your target platform (eg. JBoss EAP or Geronimo) you will need to set either -the JBOSS_HOME or GERONIMO_HOME property. By default, these properties are assumed to be -set from your environment. This can be modified in the build.xml file. - -JBoss EAP 5.x, JBoss 6.x - To use the sample application you will need to have JBoss EAP 5.x or JBoss 6.x running. - -Geronimo 2.x - To use the sample application you will need to have Geronimo 2.x running. - -Apache Qpid Broker - To run the sample it is assumed you have an Apache Qpid C++ broker configured and running. - The example code assumes that the broker will run at localhost on port 5672. This can be - modified within the build.xml file if this does not suit your particular environment. - - -Quickstart -========== -After satifsying the above requirements you are ready to deploy and run the example application. -The steps to deploy and run in the supported application servers are largely the same, however, -if you are targeting JBoss you will either need to modify the property in the example build.xml file - - - <property name="target.platform" value="geronimo"/> - -to be jboss - - <property name="target.platform" value="jboss"/> - -or set this property via the command line. - -Example: - - ant -Dtarget.platform=jboss <target> - -**Note** -Any time you wish to change platforms, this property needs to be modified and a complete clean -and rebuild needs to be performed. - -Step 1 -- Package, Deploy and configure the Qpid JCA adapter - -The core component of the example is the Qpid JCA adapter. The following lists the steps -for the respective platforms - -**Note** - -Regardless of platform, if you are building the Qpid JCA adapter from source code -you will need to use to package the RAR file via the Ant build system. To do this, from -the example directory execute - - ant deploy-rar - -This task packages the adapter and includes the necessary dependent jar files. - - -JBoss - There are no additional steps to package the adapter for JBoss deployment. Simply copy - the qpid-ra-<qpid.version>rar to your JBoss deploy directory. - - To configure the Qpid JCA Adapter in JBoss the *-ds.xml file mechanism is used. A sample - file is provided in the conf directory. - - If the defaults are suitable, you can simply execute - - ant deploy-ds - - While any property can be modified in the qpid-jca-ds.xml file, typically you will want to - change the URL of the broker to which you are trying to connect. Rather than modifying - the qpid-jca-ds.xml file directly you can modify the - - <property name="broker.url" value="amqp://anonymous:@client/test?brokerlist='tcp://localhost:5672?sasl_mechs='ANONYMOUS''"/> - - line in the build.xml file. This will dynamically insert the broker.url value into the qpid-jca-ds.xml file. - - Once this file is copied to your JBoss deploy directory and you received no exceptions, the adapter is now deployed, configured - and ready for use. - -Geronimo - By default, the Qpid JCA adapter ships with the geronimo-ra.xml deployment plan embedded - in the RAR file. This file is located in the META-INF directory alongside the ra.xml file. - By default the adapter is configured to access a broker located at localhost with the - default port of 5672. The ANONYMOUS security mechanism is also in use. If this is not - desirable, you have two approaches to configure the adapter. - - - 1) Extract the META-INF/ra.xml file from the RAR file, modify and recompress the RAR archive - with the updated contents. - - 2) Use the example build system to package the adapter. The example build.xml file includes - a target - - package-rar - - that can be used to package the RAR file as well as allowing changes to the geronimo-ra.xml - file without having to extract the RAR file by hand. The conf/geronimo-ra.xml file is used - when you use the example build system. - - While any property can be modified in the geronimo-ra.xml file, typically you will want to - change the URL of the broker to which you are trying to connect. Rather than modifying - the geronimo-ra.xml file directly you can modify the - - - <property name="broker.url" value="amqp://anonymous:@client/test?brokerlist='tcp://10.0.1.44:5672?sasl_mechs='ANONYMOUS''"/> - - line in the build.xml file. This will dynamically insert the broker.url value into the geronimo-ra.xml file. - - Once you have made your modifications you can execute - - - ant clean package-rar deploy-rar - - Note, your Geronimo server must be running and your GERONIMO_HOME environment variable must be set. Barring any exceptions, the - adapter is now deployed and ready for use in Geronimo. - - -Step 2 -- Deploy the application component(s). - -As previously mentioned, the adapter comes with a variety of EE components for use in your respective application server. You can choose to deploy -these components individually, or as a single EAR archive. This document assumes that you will use the EAR to deploy and run the example. - -The command to package and deploy the EAR archive is the same across application servers. Executing the following command - -ant deploy-ear - -will, depending upon platform, package the EAR and deploy the archive in your respective environment. Once this step is executed, the example -is ready for use. - - -Step 3 -- Test the Example - -The Qpid JCA example provides an EJB application, as well as a Web application. Both can be used to test/run the example: - -EJB -If you want to use the EJB application to test the example you can execute - - ant run-client - -Running this command will perform a JNDI lookup of the SLSB in either JBoss or Geronimo and send a simple string to the SLSB. The SLSB will receive -this string, construct a JMS message and place this message on a configured queue. The MDB will in turn receive this message and print the contents -to the console. - -The main properties involved in this task are - -server.host -jndi.context - -These vary depending upon which application server you are runnning. These can be modified to suit your environment. Looking at the run-client task you -will see the following: - - - <sysproperty key="qpid.ejb.name" value="qpid-jcaex/QpidTestBean/remote"/> - -This is the JNDI name of the SLSB component and it varies by application server. Typically you do not have to change this. Also, the task supports another property - - - <sysproperty key="qpid.message" value="insert-value-here"/> - -You can set this property if you want to modify the message contents being routed through the system. - -Web -The Qpid JCA Example comes with a web application. To access the web component, simply use a browser of your choice and navigate to - -http://<server-host-name>:<server-port>/qpid-jca-web/qpid - -where server-host and server-port are the host and port where you are running your application server. By default this is localhost:8080. Similar to the EJB component, -the web application supports a few options: - - -http://<server-host-name>:<server-port>/qpid-jca-web/qpid?messsage=<yourmessage> - -will allow you to customize the message contents that are routed through the system. By default, the Web application posts to a configured queue in the system. If you want to -test XA functionality, or use an alternate approach, you can specify - - -http://<server-host-name>:<server-port>/qpid-jca-web/qpid?useEJB=true - -instead of posting to a queue, the web application will use the local interface of the EJB component to send the message. This is functionally equivalent to running the -RMI client. - - -Summary -======= -While conceptually simple, the Qpid JCA example provides a majority of the component types and messaging patterns you are most likely to use your development efforts. -With the Web and EJB components, you can experiment with various aspects of JCA as well as EE development in general using the Qpid Broker as your messaging provider. -While this documentation highlights the major components and steps needed to take to get the example running, the possiblities for modifcation are numerous. You are -encouraged to experiment with the example as you develop your own messaging applications. - - diff --git a/java/jca/example/build-geronimo-properties.xml b/java/jca/example/build-geronimo-properties.xml index 2251b7a2df..02ecb53134 100644 --- a/java/jca/example/build-geronimo-properties.xml +++ b/java/jca/example/build-geronimo-properties.xml @@ -22,18 +22,31 @@ <property name="jndi.scheme" value="name"/> - <!-- - <property name="qpid.xacf.jndi.name" value="jca:/qpid.jca/QpidJCAAdapter/JCAManagedConnectionFactory/QpidJMSXA"/> - --> <property name="qpid.xacf.jndi.name" value="QpidJMSXA"/> + + <property name="jndi.prefix" value="jca:/qpid.jca/QpidJCAAdapter/JCAAdminObject/"/> + + + <property name="qpid.hello.queue.jndi.name" value="HelloQueue"/> + <property name="qpid.goodbye.queue.jndi.name" value="GoodByeQueue"/> + <property name="qpid.hello.topic.jndi.name" value="HelloTopic"/> + <property name="qpid.goodbye.topic.jndi.name" value="GoodByeTopic"/> + <property name="qpid.request.queue.jndi.name" value="RequestQueue"/> + <property name="qpid.response.queue.jndi.name" value="ResponseQueue"/> + + <!-- <property name="qpid.cf.jndi.name" value="jca:/qpid.jca/QpidJCAAdapter/JCAAdminObject/QpidConnectionFactory"/> <property name="qpid.hello.queue.jndi.name" value="jca:/qpid.jca/QpidJCAAdapter/JCAAdminObject/HelloQueue"/> <property name="qpid.goodbye.queue.jndi.name" value="jca:/qpid.jca/QpidJCAAdapter/JCAAdminObject/GoodByeQueue"/> - <property name="qpid.responder.queue.jndi.name" value="jca:/qpid.jca/QpidJCAAdapter/JCAAdminObject/ResponderQueue"/> <property name="qpid.hello.topic.jndi.name" value="jca:/qpid.jca/QpidJCAAdapter/JCAAdminObject/HelloTopic"/> <property name="qpid.goodbye.topic.jndi.name" value="jca:/qpid.jca/QpidJCAAdapter/JCAAdminObject/GoodByeTopic"/> + <property name="qpid.request.queue.jndi.name" value="jca:/qpid.jca/QpidJCAAdapter/JCAAdminObject/RequestQueue"/> + <property name="qpid.response.queue.jndi.name" value="jca:/qpid.jca/QpidJCAAdapter/JCAAdminObject/ResponseQueue"/> + --> <property name="qpid.ejb.jndi.name" value="name="QpidTestEJB""/> <property name="qpid.ejb.name" value="QpidTestBeanRemote"/> + <property name="qpid.client.cf.jndi.name" value="${jndi.prefix}/QpidConnectionFactory"/> + <property name="qpid.client.dest.jndi.name" value="${jndi.prefix}/${qpid.hello.queue.jndi.name}"/> <property name="jndi.context" value="org.openejb.client.RemoteInitialContextFactory"/> <property name="server.host" value="ejbd://localhost:4201"/> diff --git a/java/jca/example/build-glassfish-properties.xml b/java/jca/example/build-glassfish-properties.xml new file mode 100644 index 0000000000..94c79be931 --- /dev/null +++ b/java/jca/example/build-glassfish-properties.xml @@ -0,0 +1,135 @@ +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - +--> +<project name="qpid-jca-example-glassfish-properties" basedir="." default=""> + + <property name="jndi.scheme" value="name"/> + <property name="jndi.prefix" value=""/> + + <property name="qpid.xacf.jndi.name" value="QpidJMSXA"/> + <property name="qpid.hello.topic.jndi.name" value="HelloTopic"/> + <property name="qpid.goodbye.topic.jndi.name" value="GoodByeTopic"/> + <property name="qpid.hello.queue.jndi.name" value="HelloQueue"/> + <property name="qpid.goodbye.queue.jndi.name" value="GoodByeQueue"/> + <property name="qpid.request.queue.jndi.name" value="QpidRequestQueue"/> + <property name="qpid.response.queue.jndi.name" value="QpidResponseQueue"/> + <property name="qpid.ejb.jndi.name" value="mappedName="QpidTestEJB""/> + <property name="qpid.ejb.ref.name" value="QpidTestBean/local"/> + <property name="qpid.ejb.name" value="QpidTestBean#org.apache.qpid.jca.example.ejb.QpidTestRemote"/> + <property name="qpid.client.cf.jndi.name" value="QpidConnectionFactory"/> + <property name="qpid.client.dest.jndi.name" value="${qpid.hello.queue.jndi.name}"/> + + <property name="jndi.context" value="com.sun.enterprise.naming.SerialInitContextFactory"/> + <property name="server.host" value="iiop://localhost:3700"/> + <property name="glassfish.home" value="${env.GLASSFISH_HOME}"/> + <property name="glassfish.domain" value="domain1"/> + <property name="glassfish.user" value=""/> + <property name="glassfish.password" value=""/> + + <path id="compile.classpath"> + <fileset dir="${glassfish.home}/glassfish/modules"> + <include name="javax.ejb.jar"/> + <include name="javax.transaction.jar"/> + <include name="javax.jms.jar"/> + <include name="javax.resource.jar"/> + <include name="javax.servlet.jar"/> + </fileset> + + <fileset dir="${glassfish.home}/glassfish/domains/${glassfish.domain}/lib/ext"> + <include name="slf4j-api-*.jar"/> + </fileset> + </path> + + <path id="run.classpath"> + <fileset dir="${lib.dir}"> + <include name="qpid-ra-*.jar"/> + <include name="qpid-client-*.jar"/> + <include name="qpid-common-*.jar"/> + </fileset> + + <fileset dir="${glassfish.home}/glassfish/lib/"> + <include name="gf-client.jar"/> + </fileset> + + <fileset dir="${glassfish.home}/glassfish/modules"> + <include name="javax.ejb.jar"/> + <include name="javax.transaction.jar"/> + <include name="javax.jms.jar"/> + <include name="javax.resource.jar"/> + <include name="javax.servlet.jar"/> + </fileset> + <fileset dir="${glassfish.home}/glassfish/domains/${glassfish.domain}/lib/ext"> + <include name="slf4j-api-*.jar"/> + </fileset> + </path> + + <filterset id="extra.filterset"> + <filter token="rar.ver" value="${qpid.ver}"/> + </filterset> + + <macrodef name="glassfish"> + <attribute name="user" default="${glassfish.user}"/> + <attribute name="password" default="${glassfish.password}"/> + <attribute name="action" default="list-applications"/> + <attribute name="module"/> + <attribute name="plan" default=""/> + <sequential> + <exec executable="${glassfish.home}/bin/asadmin"> + <arg line="@{action} @{module} @{plan}"/> + </exec> + </sequential> + </macrodef> + + <target name="package-rar" depends="compile"> + <jar destfile="${build.dir}/${rar.name}"/> + </target> + + <target name="deploy-rar" depends="package-rar" description="Deploy the RAR file."> + <glassfish action="deploy" module="${qpid.jca.dir}/${rar.name}"/> + <glassfish action="add-resources" module="${gen.dir}/glassfish-resources.xml"/> + </target> + + + <target name="undeploy-resources"> + <glassfish action="delete-admin-object" module="${qpid.hello.topic.jndi.name}"/> + <glassfish action="delete-admin-object" module="${qpid.goodbye.topic.jndi.name}"/> + <glassfish action="delete-admin-object" module="${qpid.hello.queue.jndi.name}"/> + <glassfish action="delete-admin-object" module="${qpid.goodbye.queue.jndi.name}"/> + <glassfish action="delete-admin-object" module="${qpid.request.queue.jndi.name}"/> + <glassfish action="delete-admin-object" module="${qpid.response.queue.jndi.name}"/> + <glassfish action="delete-connector-connection-pool" module="--cascade true QpidJMSXAPool"/> + <glassfish action="delete-connector-connection-pool" module="--cascade true QpidJMSPool"/> + <glassfish action="delete-resource-adapter-config" module="QpidResourceAdapter"/> + </target> + + <target name="undeploy-rar" description="Deploy the RAR file."> + <glassfish action="undeploy" module="--cascade true qpid-ra-${qpid.ver}"/> + </target> + + <target name="deploy-ear" description="Deploy the EAR file." depends="package-ear"> + <glassfish action="deploy" module="${build.dir}/${ear.name}"/> + </target> + + <target name="undeploy-ear" description="Undeploy the EAR file."> + <glassfish action="undeploy" module="qpid-jcaex"/> + </target> +</project> + + diff --git a/java/jca/example/build-jboss-properties.xml b/java/jca/example/build-jboss-properties.xml index 5fc4053cf8..fd38274630 100644 --- a/java/jca/example/build-jboss-properties.xml +++ b/java/jca/example/build-jboss-properties.xml @@ -21,16 +21,21 @@ <project name="qpid-jca-example-jboss-properties" basedir="." default=""> <property name="jndi.scheme" value="mappedName"/> + <property name="jndi.prefix" value=""/> + <property name="qpid.xacf.jndi.name" value="java:QpidJMSXA"/> <property name="qpid.cf.jndi.name" value="QpidConnectionFactory"/> <property name="qpid.hello.topic.jndi.name" value="HelloTopic"/> <property name="qpid.goodbye.topic.jndi.name" value="GoodByeTopic"/> <property name="qpid.hello.queue.jndi.name" value="HelloQueue"/> <property name="qpid.goodbye.queue.jndi.name" value="GoodByeQueue"/> - <property name="qpid.responder.queue.jndi.name" value="QpidResponderQueue"/> + <property name="qpid.request.queue.jndi.name" value="QpidRequestQueue"/> + <property name="qpid.response.queue.jndi.name" value="QpidResponseQueue"/> <property name="qpid.ejb.jndi.name" value="mappedName="QpidTestEJB""/> <property name="qpid.ejb.ref.name" value="QpidTestBean/local"/> <property name="qpid.ejb.name" value="qpid-jcaex/QpidTestBean/remote"/> + <property name="qpid.client.cf.jndi.name" value="${jndi.prefix}/QpidConnectionFactory"/> + <property name="qpid.client.dest.jndi.name" value="${jndi.prefix}/${qpid.hello.queue.jndi.name}"/> <property name="jndi.context" value="org.jnp.interfaces.NamingContextFactory"/> <property name="server.host" value="jnp://localhost:1099"/> diff --git a/java/jca/example/build-jboss7-properties.xml b/java/jca/example/build-jboss7-properties.xml new file mode 100644 index 0000000000..68ecd8a4f4 --- /dev/null +++ b/java/jca/example/build-jboss7-properties.xml @@ -0,0 +1,133 @@ +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - +--> +<project name="qpid-jca-example-jboss7-properties" basedir="." default=""> + + <property name="jndi.scheme" value="name"/> + <property name="jndi.prefix" value=""/> + + <property name="qpid.xacf.jndi.name" value="java:/QpidJMSXA"/> + <property name="qpid.cf.jndi.name" value="QpidConnectionFactory"/> + <property name="qpid.hello.topic.jndi.name" value="java:jboss/exported/HelloTopic"/> + <property name="qpid.goodbye.topic.jndi.name" value="java:jboss/exported/GoodByeTopic"/> + <property name="qpid.hello.queue.jndi.name" value="java:jboss/exported/HelloQueue"/> + <property name="qpid.goodbye.queue.jndi.name" value="java:jboss/exported/GoodByeQueue"/> + <property name="qpid.request.queue.jndi.name" value="java:jboss/exported/QpidRequestQueue"/> + <property name="qpid.response.queue.jndi.name" value="java:jboss/exported/QpidResponseQueue"/> + + <property name="qpid.ejb.jndi.name" value="mappedName="QpidTestEJB""/> + <property name="qpid.ejb.ref.name" value="QpidTestBean/local"/> + <property name="qpid.ejb.name" value="ejb:qpid-jcaex/qpid-jcaex-ejb/QpidTestBean!org.apache.qpid.jca.example.ejb.QpidTestRemote"/> + + <property name="qpid.client.cf.jndi.name" value="${jndi.prefix}/QpidConnectionFactory"/> + <property name="qpid.client.dest.jndi.name" value="${jndi.prefix}/HelloQueue"/> + <property name="jndi.context" value="org.jboss.naming.remote.client.InitialContextFactory"/> + <property name="server.host" value="remote://localhost:4447"/> + + + <property name="jboss.server.config" value="standalone"/> + + <property name="jboss.home" location="${env.JBOSS_HOME}"/> + <property name="jboss.server" value="${jboss.server.config}"/> + <property name="jboss.deploy" location="${jboss.home}/${jboss.server}/deployments"/> + <property name="jboss.modules" location="${jboss.home}/modules"/> + <property name="jboss.config.dir" location="${jboss.home}/${jboss.server}/configuration/"/> + <property name="jboss.client" location="${jboss.home}/bin/client"/> + + <path id="compile.classpath"> + <fileset dir="${jboss.modules}/javax/jms/api/main"> + <include name="jboss-jms-api_1.1_spec-1.0.1.Final.jar"/> + </fileset> + <fileset dir="${jboss.modules}/javax/ejb/api/main"> + <include name="jboss-ejb-api_3.1_spec-1.0.2.Final.jar"/> + </fileset> + <fileset dir="${jboss.modules}/javax/servlet/api/main"> + <include name="jboss-servlet-api_3.0_spec-1.0.1.Final.jar"/> + </fileset> + <fileset dir="${jboss.modules}/javax/transaction/api/main"> + <include name="jboss-transaction-api_1.1_spec-1.0.1.Final.jar"/> + </fileset> + <fileset dir="${jboss.modules}/org/slf4j/main"> + <include name="slf4j-api-1.6.1.jar"/> + </fileset> + </path> + + <path id="run.classpath"> + <fileset dir="${jboss.client}"> + <include name="jboss-client.jar"/> + </fileset> + <fileset dir="${lib.dir}"> + <include name="qpid-ra-*.jar"/> + <include name="qpid-client-*.jar"/> + <include name="qpid-common-*.jar"/> + </fileset> + <fileset dir="${jboss.modules}/org/slf4j/main"> + <include name="slf4j-api-1.6.1.jar"/> + </fileset> + <fileset dir="../../build/lib"> + <include name="slf4j*.jar"/> + <include name="log4j*.jar"/> + </fileset> + <fileset dir="${jboss.modules}/org/jboss/ejb-client/main/"> + <include name="jboss-ejb-client-1.0.6.CR1.jar"/> + </fileset> + + </path> + + <filterset id="extra.filterset"/> + + <!-- Deployment is target specific so is included here --> + <target name="deploy-rar" description="Deploy the RAR file."> + <copy todir="${jboss.deploy}" overwrite="true"> + <fileset dir="${qpid.jca.dir}"> + <include name="${rar.name}"/> + </fileset> + </copy> + </target> + + <target name="undeploy-rar" description="Undeploys the RAR deployment."> + <delete file="${jboss.deploy}/${rar.name}"/> + </target> + + <target name="deploy-ear" depends="package-ear" description="Deploys the EAR archive."> + <copy todir="${jboss.deploy}" overwrite="true"> + <fileset dir="${build.dir}"> + <include name="${ear.name}"/> + </fileset> + </copy> + </target> + + <target name="undeploy-ear" description="Undeploys the EAR archive."> + <delete file="${jboss.deploy}/${ear.name}"/> + </target> + + <target name="deploy-config" depends="generate" description="Deploys the standalone file to the JBoss environment."> + <copy todir="${jboss.config.dir}" overwrite="true"> + <fileset dir="${gen.dir}"> + <include name="${jboss.server.config}.xml"/> + </fileset> + </copy> + </target> + + <target name="undeploy-ds" description="Undeploys the ds.xml file from the JBoss environment."> + <delete file="${jboss.deploy}/qpid-jca-ds.xml"/> + </target> + +</project> diff --git a/java/jca/example/build.xml b/java/jca/example/build.xml index 2717ce84d7..7a75f9abc6 100644 --- a/java/jca/example/build.xml +++ b/java/jca/example/build.xml @@ -20,7 +20,7 @@ --> <project name="qpid-jca-example" default="help" basedir=""> - <!-- Valid target platforms are currently geronimo & jboss --> + <!-- Valid target platforms are currently geronimo, jboss, jboss7, glassfish --> <property name="target.platform" value="geronimo"/> <!-- Change to BURL for older syntax support --> @@ -72,7 +72,6 @@ <filter token="rar.name" value="${rar.name}"/> <filter token="ejb.name" value="${ejb.name}"/> <filter token="war.name" value="${war.name}"/> - <filter token="broker.url" value="${broker.url}"/> <filter token="qpid.hello.topic.dest.address" value="${qpid.hello.topic.dest.address}"/> @@ -80,7 +79,8 @@ <filter token="qpid.hellogoodbye.topic.dest.address" value="${qpid.hellogoodbye.topic.dest.address}"/> <filter token="qpid.hello.queue.dest.address" value="${qpid.hello.queue.dest.address}"/> <filter token="qpid.goodbye.queue.dest.address" value="${qpid.goodbye.queue.dest.address}"/> - <filter token="qpid.responder.queue.dest.address" value="${qpid.responder.queue.dest.address}"/> + <filter token="qpid.request.queue.dest.address" value="${qpid.request.queue.dest.address}"/> + <filter token="qpid.response.queue.dest.address" value="${qpid.response.queue.dest.address}"/> </filterset> <filterset refid="extra.filterset"/> @@ -91,12 +91,14 @@ <filter token="rar.name" value="${rar.name}"/> <filter token="broker.url" value="${broker.url}"/> <filter token="jndi.scheme" value="${jndi.scheme}"/> + <filter token="jndi.prefix" value="${jndi.prefix}"/> <filter token="qpid.xacf.jndi.name" value="${qpid.xacf.jndi.name}"/> <filter token="qpid.hello.topic.jndi.name" value="${qpid.hello.topic.jndi.name}"/> <filter token="qpid.goodbye.topic.jndi.name" value="${qpid.goodbye.topic.jndi.name}"/> <filter token="qpid.hello.queue.jndi.name" value="${qpid.hello.queue.jndi.name}"/> <filter token="qpid.goodbye.queue.jndi.name" value="${qpid.goodbye.queue.jndi.name}"/> - <filter token="qpid.responder.queue.jndi.name" value="${qpid.responder.queue.jndi.name}"/> + <filter token="qpid.request.queue.jndi.name" value="${qpid.request.queue.jndi.name}"/> + <filter token="qpid.response.queue.jndi.name" value="${qpid.response.queue.jndi.name}"/> <filter token="qpid.ejb.jndi.name" value="${qpid.ejb.jndi.name}"/> </filterset> </copy> @@ -111,6 +113,9 @@ <classes dir="${build.classes.dir}"> <include name="org/apache/qpid/jca/example/web/**"/> </classes> + <metainf dir="${gen.dir}"> + <include name="glassfish-web.xml"/> + </metainf> </war> </target> @@ -119,6 +124,7 @@ <include name="org/apache/qpid/jca/example/ejb/**/*.class"/> <metainf dir="${gen.dir}"> <include name="jboss.xml"/> + <include name="glassfish-ejb-jar.xml"/> </metainf> </jar> </target> @@ -141,10 +147,13 @@ </classpath> <sysproperty key="java.naming.factory.initial" value="${jndi.context}"/> <sysproperty key="java.naming.provider.url" value="${server.host}"/> + <sysproperty key="java.naming.factory.url.pkgs" value="org.jboss.ejb.client.naming"/> + <sysproperty key="jboss.ejb.client.properties.file.path" value="${conf.dir}/jboss-ejb-client.properties"/> + <sysproperty key="qpid.ejb.name" value="${qpid.ejb.name}"/> - <sysproperty key="qpid.cf.name" value="${qpid.cf.jndi.name}"/> + <sysproperty key="qpid.cf.name" value="${qpid.client.cf.jndi.name}"/> + <sysproperty key="qpid.dest.name" value="${qpid.client.dest.jndi.name}"/> <sysproperty key="qpid.dest_syntax" value="${qpid.dest_syntax}"/> - <sysproperty key="qpid.dest.name" value="${qpid.hello.queue.jndi.name}"/> <sysproperty key="log4j.configuration" value="file://${conf.dir}/log4j.properties"/> <sysproperty key="qpid.message" value="${client.message}"/> @@ -166,8 +175,8 @@ <sysproperty key="qpid.message" value="Hello, World"/> <sysproperty key="message.count" value="1"/> <sysproperty key="thread.count" value="5"/> - <sysproperty key="qpid.cf.name" value="${qpid.cf.jndi.name}"/> - <sysproperty key="qpid.dest.name" value="${qpid.responder.queue.jndi.name}"/> + <sysproperty key="qpid.cf.name" value="${qpid.client.cf.jndi.name}"/> + <sysproperty key="qpid.dest.name" value="${qpid.client.dest.jndi.name}"/> <sysproperty key="log4j.configuration" value="file://${conf.dir}/log4j.properties"/> <sysproperty key="qpid.dest_syntax" value="${qpid.dest_syntax}"/> </java> diff --git a/java/jca/example/conf/geronimo-application.xml b/java/jca/example/conf/geronimo-application.xml index a855e0fae8..384f6b2e75 100644 --- a/java/jca/example/conf/geronimo-application.xml +++ b/java/jca/example/conf/geronimo-application.xml @@ -21,7 +21,7 @@ --> <application xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-2.0" xmlns:sys="http://geronimo.apache.org/xml/ns/deployment-1.2" - xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.2" + xmlns:nam="http://geronimo.apache.org/xml/ns/naming-1.2" application-name="QpidJCAExampleApplication"> <sys:environment> diff --git a/java/jca/example/conf/geronimo-ra.xml b/java/jca/example/conf/geronimo-ra.xml index e3e74ebc62..a7511f647f 100644 --- a/java/jca/example/conf/geronimo-ra.xml +++ b/java/jca/example/conf/geronimo-ra.xml @@ -67,63 +67,73 @@ <adminobject-class>org.apache.qpid.ra.admin.QpidTopicImpl</adminobject-class> <adminobject-instance> <message-destination-name>Dummy</message-destination-name> - <config-property-setting name="destinationAddress">amq.topic</config-property-setting> + <config-property-setting name="DestinationAddress">amq.topic</config-property-setting> </adminobject-instance> </adminobject> <adminobject> <adminobject-interface>org.apache.qpid.ra.admin.QpidTopic</adminobject-interface> <adminobject-class>org.apache.qpid.ra.admin.QpidTopicImpl</adminobject-class> <adminobject-instance> - <message-destination-name>HelloTopic</message-destination-name> - <config-property-setting name="destinationAddress">@qpid.hello.topic.dest.address@</config-property-setting> + <message-destination-name>HelloTopic</message-destination-name> + <config-property-setting name="DestinationAddress">@qpid.hello.topic.dest.address@</config-property-setting> </adminobject-instance> </adminobject> <adminobject> <adminobject-interface>org.apache.qpid.ra.admin.QpidTopic</adminobject-interface> <adminobject-class>org.apache.qpid.ra.admin.QpidTopicImpl</adminobject-class> <adminobject-instance> - <message-destination-name>GoodByeTopic</message-destination-name> - <config-property-setting name="destinationAddress">@qpid.goodbye.topic.dest.address@</config-property-setting> + <message-destination-name>GoodByeTopic</message-destination-name> + <config-property-setting name="DestinationAddress">@qpid.goodbye.topic.dest.address@</config-property-setting> </adminobject-instance> </adminobject> + <!-- <adminobject> <adminobject-interface>org.apache.qpid.ra.admin.QpidTopic</adminobject-interface> <adminobject-class>org.apache.qpid.ra.admin.QpidTopicImpl</adminobject-class> <adminobject-instance> - <message-destination-name>HelloGoodByeTopic</message-destination-name> - <config-property-setting name="destinationAddress">@qpid.hellogoodbye.topic.dest.address@</config-property-setting> + <message-destination-name>jms/HelloGoodByeTopic</message-destination-name> + <config-property-setting name="DestinationAddress">@qpid.hellogoodbye.topic.dest.address@</config-property-setting> </adminobject-instance> </adminobject> + --> <adminobject> <adminobject-interface>org.apache.qpid.ra.admin.QpidQueue</adminobject-interface> <adminobject-class>org.apache.qpid.ra.admin.QpidQueueImpl</adminobject-class> <adminobject-instance> - <message-destination-name>HelloQueue</message-destination-name> - <config-property-setting name="destinationAddress">@qpid.hello.queue.dest.address@</config-property-setting> + <message-destination-name>HelloQueue</message-destination-name> + <config-property-setting name="DestinationAddress">@qpid.hello.queue.dest.address@</config-property-setting> </adminobject-instance> </adminobject> <adminobject> <adminobject-interface>org.apache.qpid.ra.admin.QpidQueue</adminobject-interface> <adminobject-class>org.apache.qpid.ra.admin.QpidQueueImpl</adminobject-class> <adminobject-instance> - <message-destination-name>GoodByeQueue</message-destination-name> - <config-property-setting name="destinationAddress">@qpid.goodbye.queue.dest.address@</config-property-setting> + <message-destination-name>GoodByeQueue</message-destination-name> + <config-property-setting name="DestinationAddress">@qpid.goodbye.queue.dest.address@</config-property-setting> </adminobject-instance> </adminobject> <adminobject> <adminobject-interface>org.apache.qpid.ra.admin.QpidQueue</adminobject-interface> <adminobject-class>org.apache.qpid.ra.admin.QpidQueueImpl</adminobject-class> <adminobject-instance> - <message-destination-name>ResponderQueue</message-destination-name> - <config-property-setting name="destinationAddress">@qpid.responder.queue.dest.address@</config-property-setting> + <message-destination-name>RequestQueue</message-destination-name> + <config-property-setting name="DestinationAddress">@qpid.request.queue.dest.address@</config-property-setting> + </adminobject-instance> + </adminobject> + <adminobject> + <adminobject-interface>org.apache.qpid.ra.admin.QpidQueue</adminobject-interface> + <adminobject-class>org.apache.qpid.ra.admin.QpidQueueImpl</adminobject-class> + <adminobject-instance> + <message-destination-name>ResponseQueue</message-destination-name> + <config-property-setting name="DestinationAddress">@qpid.response.queue.dest.address@</config-property-setting> </adminobject-instance> </adminobject> <adminobject> <adminobject-interface>javax.jms.ConnectionFactory</adminobject-interface> <adminobject-class>org.apache.qpid.ra.admin.QpidConnectionFactoryProxy</adminobject-class> <adminobject-instance> - <message-destination-name>QpidConnectionFactory</message-destination-name> - <config-property-setting name="connectionURL">@broker.url@</config-property-setting> + <message-destination-name>QpidConnectionFactory</message-destination-name> + <config-property-setting name="ConnectionURL">@broker.url@</config-property-setting> </adminobject-instance> </adminobject> </resourceadapter> diff --git a/java/jca/example/conf/glassfish-ejb-jar.xml b/java/jca/example/conf/glassfish-ejb-jar.xml new file mode 100644 index 0000000000..e3ea140472 --- /dev/null +++ b/java/jca/example/conf/glassfish-ejb-jar.xml @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE glassfish-ejb-jar PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 EJB 3.1//EN" "http://glassfish.org/dtds/glassfish-ejb-jar_3_1-1.dtd"> +<glassfish-ejb-jar> + <enterprise-beans> + <ejb> + <ejb-name>QpidHelloListenerBean</ejb-name> + <jndi-name>HelloQueue</jndi-name> + <mdb-resource-adapter> + <resource-adapter-mid>qpid-ra-@rar.ver@</resource-adapter-mid> + </mdb-resource-adapter> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <jndi-name>QpidJMSXA</jndi-name> + </resource-ref> + </ejb> + <ejb> + <ejb-name>QpidGoodByeListenerBean</ejb-name> + <jndi-name>GoodByeQueue</jndi-name> + <mdb-resource-adapter> + <resource-adapter-mid>qpid-ra-@rar.ver@</resource-adapter-mid> + </mdb-resource-adapter> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <jndi-name>QpidJMSXA</jndi-name> + </resource-ref> + </ejb> + <ejb> + <ejb-name>QpidHelloSubscriberBean</ejb-name> + <jndi-name>HelloTopic</jndi-name> + <mdb-resource-adapter> + <resource-adapter-mid>qpid-ra-@rar.ver@</resource-adapter-mid> + </mdb-resource-adapter> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <jndi-name>QpidJMSXA</jndi-name> + </resource-ref> + </ejb> + <ejb> + <ejb-name>QpidGoodByeSubscriberBean</ejb-name> + <jndi-name>GoodByeTopic</jndi-name> + <mdb-resource-adapter> + <resource-adapter-mid>qpid-ra-@rar.ver@</resource-adapter-mid> + </mdb-resource-adapter> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <jndi-name>QpidJMSXA</jndi-name> + </resource-ref> + </ejb> + <ejb> + <ejb-name>QpidJMSResponderBean</ejb-name> + <jndi-name>QpidResponderQueue</jndi-name> + <mdb-resource-adapter> + <resource-adapter-mid>qpid-ra-@rar.ver@</resource-adapter-mid> + </mdb-resource-adapter> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <jndi-name>QpidJMSXA</jndi-name> + </resource-ref> + </ejb> + <ejb> + <ejb-name>QpidTestBean</ejb-name> + <jndi-name>QpidTestBean</jndi-name> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <jndi-name>QpidJMSXA</jndi-name> + </resource-ref> + </ejb> + </enterprise-beans> +</glassfish-ejb-jar> + diff --git a/java/jca/example/conf/glassfish-resources.xml b/java/jca/example/conf/glassfish-resources.xml new file mode 100644 index 0000000000..9eab4302d5 --- /dev/null +++ b/java/jca/example/conf/glassfish-resources.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE resources PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN" "http://glassfish.org/dtds/glassfish-resources_1_5.dtd"> +<resources> + + + <resource-adapter-config name="QpidResourceAdapter" resource-adapter-name="qpid-ra-@rar.ver@" thread-pool-ids="thread-pool-1"> + <property name="TransactionManagerLocatorClass" value="org.apache.qpid.ra.tm.GlassfishTransactionManagerLocator"/> + <property name="TransactionManagerLocatorMethod" value="getTm"/> + </resource-adapter-config> + + <!--XAConnectionFactory--> + <connector-connection-pool + name="QpidJMSXAPool" + resource-adapter-name="qpid-ra-@rar.ver@" + connection-definition-name="org.apache.qpid.ra.QpidRAConnectionFactory" + transaction-support="XATransaction" + ping="true"> + <property name="connectionURL" value="@broker.url@"/> + <property name="SessionDefaultType" value="javax.jms.Queue"/> + </connector-connection-pool> + + <connector-resource jndi-name="QpidJMSXA" pool-name="QpidJMSXAPool"/> + + <!--LocalTransaction ConnectionFactory + <connector-connection-pool + name="QpidJMSPool" + resource-adapter-name="qpid-ra-@rar.ver@" + connection-definition-name="org.apache.qpid.ra.QpidRAConnectionFactory" + transaction-support="LocalTransaction" + ping="true"> + <property name="connectionURL" value="@broker.url@"/> + <property name="SessionDefaultType" value="javax.jms.Queue"/> + <property name="UseLocalTx" value="true"/> + </connector-connection-pool> + + + <connector-resource jndi-name="QpidJMS" pool-name="QpidJMSPool"/> + + --> + <!--Destinations--> + <admin-object-resource jndi-name="HelloQueue" res-adapter="qpid-ra-@rar.ver@" res-type="org.apache.qpid.ra.admin.QpidQueue" class-name="org.apache.qpid.ra.admin.QpidQueueImpl"> + <property name="DestinationAddress" value="@qpid.hello.queue.dest.address@"/> + </admin-object-resource> + + <admin-object-resource jndi-name="GoodByeQueue" res-adapter="qpid-ra-@rar.ver@" res-type="org.apache.qpid.ra.admin.QpidQueue" class-name="org.apache.qpid.ra.admin.QpidQueueImpl"> + <property name="DestinationAddress" value="@qpid.goodbye.queue.dest.address@"/> + </admin-object-resource> + + <admin-object-resource jndi-name="HelloTopic" res-adapter="qpid-ra-@rar.ver@" res-type="org.apache.qpid.ra.admin.QpidTopic" class-name="org.apache.qpid.ra.admin.QpidTopicImpl"> + <property name="DestinationAddress" value="@qpid.hello.topic.dest.address@"/> + </admin-object-resource> + + <admin-object-resource jndi-name="GoodByeTopic" res-adapter="qpid-ra-@rar.ver@" res-type="org.apache.qpid.ra.admin.QpidTopic" class-name="org.apache.qpid.ra.admin.QpidTopicImpl"> + <property name="DestinationAddress" value="@qpid.goodbye.topic.dest.address@"/> + </admin-object-resource> + + <!-- + <admin-object-resource jndi-name="HelloGoodByeTopic" res-adapter="qpid-ra-@rar.ver@" res-type="org.apache.qpid.ra.admin.QpidTopic" class-name="org.apache.qpid.ra.admin.QpidTopicImpl"> + <property name="DestinationAddress" value="@qpid.hellogoodbye.topic.dest.address@"/> + </admin-object-resource> + --> + <admin-object-resource jndi-name="QpidRequestQueue" res-adapter="qpid-ra-@rar.ver@" res-type="org.apache.qpid.ra.admin.QpidQueue" class-name="org.apache.qpid.ra.admin.QpidQueueImpl"> + <property name="DestinationAddress" value="@qpid.request.queue.dest.address@"/> + </admin-object-resource> + + <admin-object-resource jndi-name="QpidResponseQueue" res-adapter="qpid-ra-@rar.ver@" res-type="org.apache.qpid.ra.admin.QpidQueue" class-name="org.apache.qpid.ra.admin.QpidQueueImpl"> + <property name="DestinationAddress" value="@qpid.response.queue.dest.address@"/> + </admin-object-resource> + + <admin-object-resource jndi-name="QpidConnectionFactory" res-adapter="qpid-ra-@rar.ver@" res-type="javax.jms.ConnectionFactory" class-name="org.apache.qpid.ra.admin.QpidConnectionFactoryProxy"> + <property name="ConnectionURL" value="@broker.url@"/> + </admin-object-resource> + +</resources> diff --git a/java/jca/example/conf/glassfish-web.xml b/java/jca/example/conf/glassfish-web.xml new file mode 100644 index 0000000000..950ee73d51 --- /dev/null +++ b/java/jca/example/conf/glassfish-web.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd"> +<glassfish-web-app> + + <context-root>qpid-jca-web</context-root> + + <ejb-ref> + <ejb-ref-name>QpidTestBean</ejb-ref-name> + <jndi-name>QpidTestBean</jndi-name> + </ejb-ref> + + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <jndi-name>QpidJMSXA</jndi-name> + </resource-ref> + <resource-env-ref> + <res-env-ref-name>HelloQueue</res-env-ref-name> + <jndi-name>HelloQueue</jndi-name> + </resource-env-ref> + <resource-ref> + <res-ref-name>HelloTopic</res-ref-name> + <jndi-name>HelloTopic</jndi-name> + </resource-ref> + + +</glassfish-web-app> diff --git a/java/jca/example/conf/jboss-ejb-client.properties b/java/jca/example/conf/jboss-ejb-client.properties new file mode 100644 index 0000000000..8bf1075c14 --- /dev/null +++ b/java/jca/example/conf/jboss-ejb-client.properties @@ -0,0 +1,12 @@ +endpoint.name=client-endpoint +remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false + +remote.connections=default + +remote.connection.default.host=localhost +remote.connection.default.port = 4447 +remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false + +remote.connection.default.username=wmprice +remote.connection.default.password=72whtu78 + diff --git a/java/jca/example/conf/jboss-web.xml b/java/jca/example/conf/jboss-web.xml index edacf8d418..32a97d1c35 100644 --- a/java/jca/example/conf/jboss-web.xml +++ b/java/jca/example/conf/jboss-web.xml @@ -25,6 +25,11 @@ <res-type>javax.jms.ConnectionFactory</res-type> <jndi-name>java:/QpidJMSXA</jndi-name> </resource-ref> + <resource-ref> + <res-ref-name>QpidJMS</res-ref-name> + <res-type>javax.jms.ConnectionFactory</res-type> + <jndi-name>java:/QpidJMS</jndi-name> + </resource-ref> <ejb-local-ref> <ejb-ref-name>QpidTestBean</ejb-ref-name> <jndi-name>qpid-jcaex/QpidTestBean/local</jndi-name> diff --git a/java/jca/example/conf/log4j.properties b/java/jca/example/conf/log4j.properties index f1847f4418..1139ab9e85 100644 --- a/java/jca/example/conf/log4j.properties +++ b/java/jca/example/conf/log4j.properties @@ -1,3 +1,21 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# log4j.rootLogger=DEBUG, CONSOLE, FILE #Console Appender diff --git a/java/jca/example/conf/qpid-jca-ds.xml b/java/jca/example/conf/qpid-jca-ds.xml index 80fb828b55..ad75876808 100644 --- a/java/jca/example/conf/qpid-jca-ds.xml +++ b/java/jca/example/conf/qpid-jca-ds.xml @@ -27,7 +27,7 @@ <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> <attribute name="Type">org.apache.qpid.ra.admin.QpidTopic</attribute> <attribute name="Properties"> - destinationAddress=@qpid.hello.topic.dest.address@ + DestinationAddress=@qpid.hello.topic.dest.address@ </attribute> </mbean> @@ -37,7 +37,7 @@ <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> <attribute name="Type">org.apache.qpid.ra.admin.QpidTopic</attribute> <attribute name="Properties"> - destinationAddress=@qpid.goodbye.topic.dest.address@ + DestinationAddress=@qpid.goodbye.topic.dest.address@ </attribute> </mbean> @@ -47,7 +47,7 @@ <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> <attribute name="Type">org.apache.qpid.ra.admin.QpidTopic</attribute> <attribute name="Properties"> - destinationAddress=@qpid.hellogoodbye.topic.dest.address@ + DestinationAddress=@qpid.hellogoodbye.topic.dest.address@ </attribute> </mbean> @@ -57,7 +57,7 @@ <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> <attribute name="Type">org.apache.qpid.ra.admin.QpidQueue</attribute> <attribute name="Properties"> - destinationAddress=@qpid.hello.queue.dest.address@ + DestinationAddress=@qpid.hello.queue.dest.address@ </attribute> </mbean> @@ -67,27 +67,36 @@ <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> <attribute name="Type">org.apache.qpid.ra.admin.QpidQueue</attribute> <attribute name="Properties"> - destinationAddress=@qpid.goodbye.queue.dest.address@ + DestinationAddress=@qpid.goodbye.queue.dest.address@ </attribute> </mbean> <mbean code="org.jboss.resource.deployment.AdminObject" - name="qpid.jca:name=QpidResponderQueue"> - <attribute name="JNDIName">QpidResponderQueue</attribute> + name="qpid.jca:name=QpidRequestQueue"> + <attribute name="JNDIName">QpidRequestQueue</attribute> <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> <attribute name="Type">org.apache.qpid.ra.admin.QpidQueue</attribute> <attribute name="Properties"> - destinationAddress=@qpid.responder.queue.dest.address@ + DestinationAddress=@qpid.request.queue.dest.address@ </attribute> </mbean> <mbean code="org.jboss.resource.deployment.AdminObject" + name="qpid.jca:name=QpidResponseQueue"> + <attribute name="JNDIName">QpidResponseQueue</attribute> + <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> + <attribute name="Type">org.apache.qpid.ra.admin.QpidQueue</attribute> + <attribute name="Properties"> + DestinationAddress=@qpid.response.queue.dest.address@ + </attribute> + </mbean> + <mbean code="org.jboss.resource.deployment.AdminObject" name="qpid.jca:name=QpidConnectionFactory"> <attribute name="JNDIName">QpidConnectionFactory</attribute> <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> <attribute name="Type">javax.jms.ConnectionFactory</attribute> <attribute name="Properties"> - connectionURL=@broker.url@ + ConnectionURL=@broker.url@ </attribute> </mbean> diff --git a/java/jca/example/conf/qpid-standalone.xml b/java/jca/example/conf/qpid-standalone.xml new file mode 100644 index 0000000000..8d6137aea7 --- /dev/null +++ b/java/jca/example/conf/qpid-standalone.xml @@ -0,0 +1,422 @@ +<!-- + - + - Licensed to the Apache Software Foundation (ASF) under one + - or more contributor license agreements. See the NOTICE file + - distributed with this work for additional information + - regarding copyright ownership. The ASF licenses this file + - to you under the Apache License, Version 2.0 (the + - "License"); you may not use this file except in compliance + - with the License. You may obtain a copy of the License at + - + - http://www.apache.org/licenses/LICENSE-2.0 + - + - Unless required by applicable law or agreed to in writing, + - software distributed under the License is distributed on an + - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + - KIND, either express or implied. See the License for the + - specific language governing permissions and limitations + - under the License. + - +--> +<?xml version='1.0' encoding='UTF-8'?> + +<server xmlns="urn:jboss:domain:1.1" xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance"> + + <extensions> + <extension module="org.jboss.as.clustering.infinispan"/> + <extension module="org.jboss.as.connector"/> + <extension module="org.jboss.as.configadmin"/> + <extension module="org.jboss.as.deployment-scanner"/> + <extension module="org.jboss.as.ee"/> + <extension module="org.jboss.as.ejb3"/> + <extension module="org.jboss.as.jaxr"/> + <extension module="org.jboss.as.jaxrs"/> + <extension module="org.jboss.as.jdr"/> + <extension module="org.jboss.as.jmx"/> + <extension module="org.jboss.as.jpa"/> + <extension module="org.jboss.as.logging"/> + <extension module="org.jboss.as.mail"/> + <extension module="org.jboss.as.naming"/> + <extension module="org.jboss.as.osgi"/> + <extension module="org.jboss.as.pojo"/> + <extension module="org.jboss.as.remoting"/> + <extension module="org.jboss.as.sar"/> + <extension module="org.jboss.as.security"/> + <extension module="org.jboss.as.threads"/> + <extension module="org.jboss.as.transactions"/> + <extension module="org.jboss.as.web"/> + <extension module="org.jboss.as.webservices"/> + <extension module="org.jboss.as.weld"/> + </extensions> + + <management> + <security-realms> + <security-realm name="ManagementRealm"> + <authentication> + <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/> + </authentication> + </security-realm> + </security-realms> + <management-interfaces> + <native-interface security-realm="ManagementRealm"> + <socket-binding native="management-native"/> + </native-interface> + <http-interface security-realm="ManagementRealm"> + <socket-binding http="management-http"/> + </http-interface> + </management-interfaces> + </management> + + <profile> + <subsystem xmlns="urn:jboss:domain:logging:1.1"> + <console-handler name="CONSOLE"> + <level name="INFO"/> + <formatter> + <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/> + </formatter> + </console-handler> + <periodic-rotating-file-handler name="FILE"> + <formatter> + <pattern-formatter pattern="%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%E%n"/> + </formatter> + <file relative-to="jboss.server.log.dir" path="server.log"/> + <suffix value=".yyyy-MM-dd"/> + <append value="true"/> + </periodic-rotating-file-handler> + <logger category="com.arjuna"> + <level name="WARN"/> + </logger> + <logger category="org.apache.tomcat.util.modeler"> + <level name="WARN"/> + </logger> + <logger category="sun.rmi"> + <level name="WARN"/> + </logger> + <logger category="jacorb"> + <level name="WARN"/> + </logger> + <logger category="jacorb.config"> + <level name="ERROR"/> + </logger> + <root-logger> + <level name="DEBUG"/> + <handlers> + <handler name="CONSOLE"/> + <handler name="FILE"/> + </handlers> + </root-logger> + </subsystem> + <subsystem xmlns="urn:jboss:domain:configadmin:1.0"/> + <subsystem xmlns="urn:jboss:domain:datasources:1.0"> + <datasources> + <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true"> + <connection-url> + jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 + </connection-url> + <driver> + h2 + </driver> + <security> + <user-name> + sa + </user-name> + <password> + sa + </password> + </security> + </datasource> + <drivers> + <driver name="h2" module="com.h2database.h2"> + <xa-datasource-class> + org.h2.jdbcx.JdbcDataSource + </xa-datasource-class> + </driver> + </drivers> + </datasources> + </subsystem> + <subsystem xmlns="urn:jboss:domain:deployment-scanner:1.1"> + <deployment-scanner name="default" path="deployments" scan-interval="5000" relative-to="jboss.server.base.dir"/> + </subsystem> + <subsystem xmlns="urn:jboss:domain:ee:1.0"/> + <subsystem xmlns="urn:jboss:domain:ejb3:1.2"> + <session-bean> + <stateless> + <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/> + </stateless> + <stateful default-access-timeout="5000" cache-ref="simple"/> + <singleton default-access-timeout="5000"/> + </session-bean> + <mdb> + <resource-adapter-ref resource-adapter-name="@rar.name@"/> + <bean-instance-pool-ref pool-name="mdb-strict-max-pool"/> + </mdb> + <pools> + <bean-instance-pools> + <strict-max-pool name="slsb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/> + <strict-max-pool name="mdb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/> + </bean-instance-pools> + </pools> + <caches> + <cache name="simple" aliases="NoPassivationCache"/> + <cache name="passivating" passivation-store-ref="file" aliases="SimpleStatefulCache"/> + </caches> + <passivation-stores> + <file-passivation-store name="file"/> + </passivation-stores> + <async thread-pool-name="default"/> + <timer-service thread-pool-name="default"> + <data-store path="timer-service-data" relative-to="jboss.server.data.dir"/> + </timer-service> + <remote connector-ref="remoting-connector" thread-pool-name="default"/> + <thread-pools> + <thread-pool name="default"> + <max-threads count="10"/> + <keepalive-time time="100" unit="milliseconds"/> + </thread-pool> + </thread-pools> + </subsystem> + <subsystem xmlns="urn:jboss:domain:infinispan:1.1" default-cache-container="hibernate"> + <cache-container name="hibernate" default-cache="local-query"> + <local-cache name="entity"> + <transaction mode="NON_XA"/> + <eviction strategy="LRU" max-entries="10000"/> + <expiration max-idle="100000"/> + </local-cache> + <local-cache name="local-query"> + <transaction mode="NONE"/> + <eviction strategy="LRU" max-entries="10000"/> + <expiration max-idle="100000"/> + </local-cache> + <local-cache name="timestamps"> + <transaction mode="NONE"/> + <eviction strategy="NONE"/> + </local-cache> + </cache-container> + </subsystem> + <subsystem xmlns="urn:jboss:domain:jaxr:1.0"> + <connection-factory jndi-name="java:jboss/jaxr/ConnectionFactory"/> + <juddi-server publish-url="http://localhost:8080/juddi/publish" query-url="http://localhost:8080/juddi/query"/> + </subsystem> + <subsystem xmlns="urn:jboss:domain:jaxrs:1.0"/> + <subsystem xmlns="urn:jboss:domain:jca:1.1"> + <archive-validation enabled="false"/> + <bean-validation enabled="false"/> + <default-workmanager> + <short-running-threads> + <core-threads count="50"/> + <queue-length count="50"/> + <max-threads count="50"/> + <keepalive-time time="10" unit="seconds"/> + </short-running-threads> + <long-running-threads> + <core-threads count="50"/> + <queue-length count="50"/> + <max-threads count="50"/> + <keepalive-time time="10" unit="seconds"/> + </long-running-threads> + </default-workmanager> + </subsystem> + <subsystem xmlns="urn:jboss:domain:jdr:1.0"/> + <subsystem xmlns="urn:jboss:domain:jmx:1.1"> + <show-model value="true"/> + <remoting-connector/> + </subsystem> + <subsystem xmlns="urn:jboss:domain:jpa:1.0"> + <jpa default-datasource=""/> + </subsystem> + <subsystem xmlns="urn:jboss:domain:mail:1.0"> + <mail-session jndi-name="java:jboss/mail/Default"> + <smtp-server outbound-socket-binding-ref="mail-smtp"/> + </mail-session> + </subsystem> + <subsystem xmlns="urn:jboss:domain:naming:1.1"/> + <subsystem xmlns="urn:jboss:domain:osgi:1.2" activation="lazy"> + <properties> + <property name="org.osgi.framework.startlevel.beginning"> + 1 + </property> + </properties> + <capabilities> + <capability name="javax.servlet.api"/> + <capability name="javax.transaction.api"/> + <capability name="org.apache.felix.log" startlevel="1"/> + <capability name="org.jboss.osgi.logging" startlevel="1"/> + <capability name="org.apache.felix.configadmin" startlevel="1"/> + <capability name="org.jboss.as.osgi.configadmin" startlevel="1"/> + <capability name="org.jboss.osgi.repository" startlevel="1"/> + </capabilities> + </subsystem> + <subsystem xmlns="urn:jboss:domain:pojo:1.0"/> + <subsystem xmlns="urn:jboss:domain:remoting:1.1"> + <connector name="remoting-connector" socket-binding="remoting"/> + </subsystem> + <subsystem xmlns="urn:jboss:domain:resource-adapters:1.0"> + <resource-adapters> + <resource-adapter> + <archive> + @rar.name@ + </archive> + <transaction-support> + XATransaction + </transaction-support> + <config-property name="connectionURL"> + @broker.url@ + </config-property> + <config-property name="TransactionManagerLocatorClass"> + org.apache.qpid.ra.tm.JBoss7TransactionManagerLocator + </config-property> + <config-property name="TransactionManagerLocatorMethod"> + getTm + </config-property> + <connection-definitions> + <connection-definition class-name="org.apache.qpid.ra.QpidRAManagedConnectionFactory" jndi-name="QpidJMSXA" pool-name="QpidJMSXA"> + <config-property name="connectionURL"> + @broker.url@ + </config-property> + <config-property name="SessionDefaultType"> + javax.jms.Queue + </config-property> + </connection-definition> + </connection-definitions> + <admin-objects> + <admin-object class-name="org.apache.qpid.ra.admin.QpidConnectionFactoryProxy" jndi-name="java:jboss/exported/QpidConnectionFactory" use-java-context="false"> + <config-property name="ConnectionURL"> + @broker.url@ + </config-property> + </admin-object> + <admin-object class-name="org.apache.qpid.ra.admin.QpidTopicImpl" jndi-name="java:jboss/exported/GoodByeTopic" use-java-context="false" pool-name="GoodByeTopic"> + <config-property name="DestinationAddress"> + @qpid.hello.topic.dest.address@ + </config-property> + </admin-object> + <admin-object class-name="org.apache.qpid.ra.admin.QpidTopicImpl" jndi-name="java:jboss/exported/HelloTopic" use-java-context="false" pool-name="HelloTopic"> + <config-property name="DestinationAddress"> + @qpid.goodbye.topic.dest.address@ + </config-property> + </admin-object> + <admin-object class-name="org.apache.qpid.ra.admin.QpidQueueImpl" jndi-name="java:jboss/exported/GoodByeQueue" use-java-context="false" pool-name="GoodByeQueue"> + <config-property name="DestinationAddress"> + @qpid.goodbye.queue.dest.address@ + </config-property> + </admin-object> + <admin-object class-name="org.apache.qpid.ra.admin.QpidQueueImpl" jndi-name="java:jboss/exported/HelloQueue" use-java-context="false" pool-name="HelloQueue"> + <config-property name="DestinationAddress"> + @qpid.hello.queue.dest.address@ + </config-property> + </admin-object> + <admin-object class-name="org.apache.qpid.ra.admin.QpidQueueImpl" jndi-name="java:jboss/exported/QpidRequestQueue" use-java-context="false" pool-name="QpidRequestQueue"> + <config-property name="DestinationAddress"> + @qpid.request.queue.dest.address@ + </config-property> + </admin-object> + <admin-object class-name="org.apache.qpid.ra.admin.QpidQueueImpl" jndi-name="java:jboss/exported/QpidResponseQueue" use-java-context="false" pool-name="QpidResponseQueue"> + <config-property name="DestinationAddress"> + @qpid.response.queue.dest.address@ + </config-property> + </admin-object> + </admin-objects> + </resource-adapter> + </resource-adapters> + </subsystem> + <subsystem xmlns="urn:jboss:domain:sar:1.0"/> + <subsystem xmlns="urn:jboss:domain:security:1.1"> + <security-domains> + <security-domain name="other" cache-type="default"> + <authentication> + <login-module code="UsersRoles" flag="required"/> + </authentication> + </security-domain> + <security-domain name="jboss-web-policy" cache-type="default"> + <authorization> + <policy-module code="Delegating" flag="required"/> + </authorization> + </security-domain> + <security-domain name="jboss-ejb-policy" cache-type="default"> + <authorization> + <policy-module code="Delegating" flag="required"/> + </authorization> + </security-domain> + </security-domains> + </subsystem> + <subsystem xmlns="urn:jboss:domain:threads:1.1"/> + <subsystem xmlns="urn:jboss:domain:transactions:1.1"> + <core-environment> + <process-id> + <uuid/> + </process-id> + </core-environment> + <recovery-environment socket-binding="txn-recovery-environment" status-socket-binding="txn-status-manager"/> + <coordinator-environment default-timeout="300"/> + </subsystem> + <subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host"> + <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/> + <virtual-server name="default-host" enable-welcome-root="true"> + <alias name="localhost"/> + <alias name="example.com"/> + </virtual-server> + </subsystem> + <subsystem xmlns="urn:jboss:domain:webservices:1.0" xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:jaxwsconfig="urn:jboss:jbossws-jaxws-config:4.0"> + <modify-wsdl-address> + true + </modify-wsdl-address> + <wsdl-host> + ${jboss.bind.address:127.0.0.1} + </wsdl-host> + <endpoint-config> + <jaxwsconfig:config-name> + Standard-Endpoint-Config + </jaxwsconfig:config-name> + </endpoint-config> + <endpoint-config> + <jaxwsconfig:config-name> + Recording-Endpoint-Config + </jaxwsconfig:config-name> + <jaxwsconfig:pre-handler-chains> + <javaee:handler-chain id="recording-handlers"> + <javaee:protocol-bindings> + ##SOAP11_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP ##SOAP12_HTTP_MTOM + </javaee:protocol-bindings> + <javaee:handler> + <javaee:handler-name> + RecordingHandler + </javaee:handler-name> + <javaee:handler-class> + org.jboss.ws.common.invocation.RecordingServerHandler + </javaee:handler-class> + </javaee:handler> + </javaee:handler-chain> + </jaxwsconfig:pre-handler-chains> + </endpoint-config> + </subsystem> + <subsystem xmlns="urn:jboss:domain:weld:1.0"/> + </profile> + + <interfaces> + <interface name="management"> + <inet-address value="${jboss.bind.address.management:127.0.0.1}"/> + </interface> + <interface name="public"> + <inet-address value="${jboss.bind.address:127.0.0.1}"/> + </interface> + </interfaces> + + <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}"> + <socket-binding name="http" port="8080"/> + <socket-binding name="https" port="8443"/> + <socket-binding name="jacorb" port="3528"/> + <socket-binding name="jacorb-ssl" port="3529"/> + <socket-binding name="management-native" interface="management" port="${jboss.management.native.port:9999}"/> + <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/> + <socket-binding name="messaging" port="5445"/> + <socket-binding name="messaging-throughput" port="5455"/> + <socket-binding name="osgi-http" interface="management" port="8090"/> + <socket-binding name="remoting" port="4447"/> + <socket-binding name="txn-recovery-environment" port="4712"/> + <socket-binding name="txn-status-manager" port="4713"/> + <outbound-socket-binding name="mail-smtp"> + <remote-destination host="localhost" port="25"/> + </outbound-socket-binding> + </socket-binding-group> + + +</server> diff --git a/java/jca/example/conf/web.xml b/java/jca/example/conf/web.xml index d87c578606..6e53d7beba 100644 --- a/java/jca/example/conf/web.xml +++ b/java/jca/example/conf/web.xml @@ -29,11 +29,22 @@ <load-on-startup>1</load-on-startup> </servlet> + <servlet> + <display-name>QpidRequestResponseServlet</display-name> + <servlet-name>QpidRequestResponseServlet</servlet-name> + <servlet-class>org.apache.qpid.jca.example.web.QpidRequestResponseServlet</servlet-class> + <load-on-startup>1</load-on-startup> + </servlet> + <servlet-mapping> <servlet-name>QpidTestServlet</servlet-name> <url-pattern>/qpid</url-pattern> </servlet-mapping> + <servlet-mapping> + <servlet-name>QpidRequestResponseServlet</servlet-name> + <url-pattern>/qpid-reqresp</url-pattern> + </servlet-mapping> </web-app> diff --git a/java/jca/example/qpid-jca-example-properties.xml b/java/jca/example/qpid-jca-example-properties.xml index eb219a05e1..ab0f6267ba 100644 --- a/java/jca/example/qpid-jca-example-properties.xml +++ b/java/jca/example/qpid-jca-example-properties.xml @@ -45,8 +45,10 @@ value="hello.Queue;{create:always, node:{type:queue, x-declare:{auto-delete:true}}}"/> <property name="qpid.goodbye.queue.dest.address.ADDR" value="goodbye.Queue;{create:always, node:{type:queue, x-declare:{auto-delete:true}}}"/> - <property name="qpid.responder.queue.dest.address.ADDR" - value="responder.Queue;{create:always, node:{type:queue, x-declare:{auto-delete:true}}}"/> + <property name="qpid.request.queue.dest.address.ADDR" + value="request.Queue;{create:always, node:{type:queue, x-declare:{auto-delete:true}}}"/> + <property name="qpid.response.queue.dest.address.ADDR" + value="response.Queue;{create:always, node:{type:queue, x-declare:{auto-delete:false}}}"/> <property name="qpid.hello.topic.dest.address.BURL" value="BURL:topic://amq.topic//hello.jcaTopic?routingKey='hello.jcaTopic',autodelete='true'"/> @@ -58,8 +60,10 @@ value="BURL:direct://amq.direct//hello.Queue?routingkey='hello.Queue'"/> <property name="qpid.goodbye.queue.dest.address.BURL" value="BURL:direct://amq.direct//goodbye.Queue?routingkey='goodbye.Queue'"/> - <property name="qpid.responder.queue.dest.address.BURL" - value="BURL:direct://amq.direct//responder.Queue?routingkey='responder.Queue'"/> + <property name="qpid.request.queue.dest.address.BURL" + value="BURL:direct://amq.direct//request.Queue?routingkey='request.Queue'"/> + <property name="qpid.response.queue.dest.address.BURL" + value="BURL:direct://amq.direct//response.Queue?routingkey='response.Queue'"/> <!-- This macro allows us to construct a property name which contains a property expansion --> <macrodef name="set-address-property"> @@ -75,5 +79,6 @@ <set-address-property name="qpid.hellogoodbye.topic.dest.address" syntax="${qpid.dest_syntax}"/> <set-address-property name="qpid.hello.queue.dest.address" syntax="${qpid.dest_syntax}"/> <set-address-property name="qpid.goodbye.queue.dest.address" syntax="${qpid.dest_syntax}"/> - <set-address-property name="qpid.responder.queue.dest.address" syntax="${qpid.dest_syntax}"/> + <set-address-property name="qpid.request.queue.dest.address" syntax="${qpid.dest_syntax}"/> + <set-address-property name="qpid.response.queue.dest.address" syntax="${qpid.dest_syntax}"/> </project> diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/client/QpidRequestResponseClient.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/client/QpidRequestResponseClient.java index 734df1c0f3..fd5b3efff0 100644 --- a/java/jca/example/src/main/java/org/apache/qpid/jca/example/client/QpidRequestResponseClient.java +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/client/QpidRequestResponseClient.java @@ -42,7 +42,7 @@ public class QpidRequestResponseClient implements MessageListener, Runnable private static final Logger _log = LoggerFactory.getLogger(QpidRequestResponseClient.class); private static final String DEFAULT_CF_JNDI = "QpidConnectionFactory"; - private static final String DEFAULT_DESTINATION_JNDI = "QpidResponderQueue"; + private static final String DEFAULT_DESTINATION_JNDI = "QpidRequestQueue"; private static final String DEFAULT_MESSAGE = "Hello, World!"; private static final int DEFAULT_MESSAGE_COUNT = 1; private static final int DEFAULT_THREAD_COUNT = 1; diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidGoodByeListenerBean.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidGoodByeListenerBean.java index 9cf220de2a..bdb722a87b 100644 --- a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidGoodByeListenerBean.java +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidGoodByeListenerBean.java @@ -34,7 +34,7 @@ import org.slf4j.LoggerFactory; @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), - @ActivationConfigProperty(propertyName = "destination", propertyValue = "@qpid.goodbye.queue.jndi.name@"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "@jndi.prefix@@qpid.goodbye.queue.jndi.name@"), @ActivationConfigProperty(propertyName = "connectionURL", propertyValue = "@broker.url@"), @ActivationConfigProperty(propertyName = "useLocalTx", propertyValue = "false"), @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "10") diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidGoodByeSubscriberBean.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidGoodByeSubscriberBean.java index 64e0effb1f..f2e4d6aaa5 100644 --- a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidGoodByeSubscriberBean.java +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidGoodByeSubscriberBean.java @@ -34,10 +34,9 @@ import org.slf4j.LoggerFactory; @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), - @ActivationConfigProperty(propertyName = "destination", propertyValue = "@qpid.goodbye.topic.jndi.name@"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "@jndi.prefix@@qpid.goodbye.topic.jndi.name@"), @ActivationConfigProperty(propertyName = "connectionURL", propertyValue = "@broker.url@"), @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "NotDurable"), - @ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "hello.Topic"), @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "10") }) diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidHelloListenerBean.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidHelloListenerBean.java index 0056e7b0b8..75e0acab79 100644 --- a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidHelloListenerBean.java +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidHelloListenerBean.java @@ -42,7 +42,7 @@ import org.slf4j.LoggerFactory; @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), - @ActivationConfigProperty(propertyName = "destination", propertyValue = "@qpid.hello.queue.jndi.name@"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "@jndi.prefix@@qpid.hello.queue.jndi.name@"), @ActivationConfigProperty(propertyName = "connectionURL", propertyValue = "@broker.url@"), @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "10") }) @@ -53,7 +53,7 @@ public class QpidHelloListenerBean implements MessageListener @Resource(@jndi.scheme@="@qpid.xacf.jndi.name@") private ConnectionFactory _connectionFactory; - @Resource(@jndi.scheme@="GoodByeQueue") + @Resource(@jndi.scheme@="@qpid.goodbye.queue.jndi.name@") private Destination _queue; @Override diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidHelloSubscriberBean.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidHelloSubscriberBean.java index 560de36e48..882c85fa18 100644 --- a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidHelloSubscriberBean.java +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidHelloSubscriberBean.java @@ -42,10 +42,9 @@ import org.slf4j.LoggerFactory; @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), - @ActivationConfigProperty(propertyName = "destination", propertyValue = "@qpid.hello.topic.jndi.name@"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "@jndi.prefix@@qpid.hello.topic.jndi.name@"), @ActivationConfigProperty(propertyName = "connectionURL", propertyValue = "@broker.url@"), @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "NotDurable"), - @ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "hello.Topic"), @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "10") }) public class QpidHelloSubscriberBean implements MessageListener @@ -55,7 +54,7 @@ public class QpidHelloSubscriberBean implements MessageListener @Resource(@jndi.scheme@="@qpid.xacf.jndi.name@") private ConnectionFactory _connectionFactory; - @Resource(@jndi.scheme@="GoodByeTopic") + @Resource(@jndi.scheme@="@qpid.goodbye.topic.jndi.name@") private Destination _topic; @Override diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidJMSResponderBean.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidJMSResponderBean.java index e7b44e10ca..6e99d4fe7f 100644 --- a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidJMSResponderBean.java +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidJMSResponderBean.java @@ -27,6 +27,7 @@ import javax.ejb.ActivationConfigProperty; import javax.ejb.MessageDriven; import javax.jms.Connection; import javax.jms.ConnectionFactory; +import javax.jms.Destination; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.MessageProducer; @@ -40,7 +41,7 @@ import org.slf4j.LoggerFactory; @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), - @ActivationConfigProperty(propertyName = "destination", propertyValue = "@qpid.responder.queue.jndi.name@"), + @ActivationConfigProperty(propertyName = "destination", propertyValue = "@jndi.prefix@@qpid.request.queue.jndi.name@"), @ActivationConfigProperty(propertyName = "connectionURL", propertyValue = "@broker.url@"), @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "10") }) @@ -72,10 +73,12 @@ public class QpidJMSResponderBean implements MessageListener temp.append("QpidJMSResponderBean received message with content: [" + content); temp.append("] at " + new Date()); + connection = _connectionFactory.createConnection(); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + if(message.getJMSReplyTo() != null) { - connection = _connectionFactory.createConnection(); - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + _log.info("Sending response via JMSReplyTo"); messageProducer = session.createProducer(message.getJMSReplyTo()); response = session.createTextMessage(); response.setText(temp.toString()); @@ -83,8 +86,10 @@ public class QpidJMSResponderBean implements MessageListener } else { - _log.warn("Response was requested with no JMSReplyToDestination set. Will not respond to message."); + _log.info("JMSReplyTo is null. Will not respond to message."); } + + } } catch(Exception e) diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTestBean.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTestBean.java index 014b459699..a5f4770257 100644 --- a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTestBean.java +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTestBean.java @@ -43,10 +43,10 @@ public class QpidTestBean implements QpidTestRemote, QpidTestLocal @Resource(@jndi.scheme@="@qpid.xacf.jndi.name@") private ConnectionFactory _connectionFactory; - @Resource(@jndi.scheme@="HelloQueue") + @Resource(@jndi.scheme@="@qpid.hello.queue.jndi.name@") private Destination _queue; - @Resource(@jndi.scheme@="HelloTopic") + @Resource(@jndi.scheme@="@qpid.hello.topic.jndi.name@") private Destination _topic; @Override diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/web/QpidRequestResponseServlet.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/web/QpidRequestResponseServlet.java new file mode 100644 index 0000000000..d069a0c943 --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/web/QpidRequestResponseServlet.java @@ -0,0 +1,283 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.qpid.jca.example.web; +import java.io.IOException; +import java.lang.Thread; + +import javax.annotation.Resource; +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.InitialContext; +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.transaction.UserTransaction; + +import org.apache.qpid.jca.example.ejb.QpidTest; +import org.apache.qpid.jca.example.ejb.QpidUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@SuppressWarnings("serial") +public class QpidRequestResponseServlet extends HttpServlet +{ + private static final Logger _log = LoggerFactory.getLogger(QpidTestServlet.class); + + private static final String DEFAULT_MESSAGE = "Hello, World!"; + private static final int DEFAULT_COUNT = 1; + private static final boolean DEFAULT_XA = false; + private static final boolean DEFAULT_TX = false; + private static final boolean USE_TMP_QUEUE = false; + + @Resource(@jndi.scheme@="@qpid.xacf.jndi.name@") + private ConnectionFactory _connectionFactory; + + @Resource(@jndi.scheme@="@qpid.request.queue.jndi.name@") + private Destination _queue; + + @Resource(@jndi.scheme@="@qpid.response.queue.jndi.name@") + private Destination _responseQueue; + + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + doPost(req, resp); + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException + { + InitialContext ctx = null; + Connection connection = null; + Session session = null; + MessageProducer messageProducer = null; + UserTransaction ut = null; + boolean useXA = false; + boolean rollback = false; + boolean useTx = false; + MessageConsumer messageConsumer = null; + long startTime = 0; + + try + { + String content = (req.getParameter("message") == null) ? DEFAULT_MESSAGE : req.getParameter("message"); + int count = (req.getParameter("count") == null) ? DEFAULT_COUNT : Integer.valueOf(req.getParameter("count")); + useXA = (req.getParameter("useXA") == null) ? DEFAULT_XA : Boolean.valueOf(req.getParameter("useXA")); + useTx = (req.getParameter("useTx") == null) ? DEFAULT_TX : Boolean.valueOf(req.getParameter("useTx")); + + ctx = new InitialContext(); + + _log.debug("Environment: "); + _log.debug("Message content: " + content); + _log.debug("Message count:" + count); + _log.debug("Using XA: " + useXA); + + resp.getOutputStream().println("Environment: "); + resp.getOutputStream().println("Message content: " + content); + resp.getOutputStream().println("Message count:" + count); + resp.getOutputStream().println("Using XA: " + useXA); + + try + { + + connection = _connectionFactory.createConnection(); + + if(useXA) + { + ut = (UserTransaction)ctx.lookup("java:comp/UserTransaction"); + ut.begin(); + useTx = false; + } + + session = (useXA) ? connection.createSession(false, Session.AUTO_ACKNOWLEDGE) : connection.createSession(useTx, Session.AUTO_ACKNOWLEDGE); + messageProducer = session.createProducer(_queue); + + startTime = System.currentTimeMillis(); + + for(int i = 0; i < count; i++) + { + TextMessage message = session.createTextMessage(content); + message.setJMSReplyTo(_responseQueue); + messageProducer.send(message); + } + + } + catch(Exception e) + { + rollback = true; + + if(useXA && ut != null) + { + try + { + ut.setRollbackOnly(); + } + catch(Exception ex) + { + _log.error(ex.getMessage(), ex); + throw new ServletException(ex.getMessage(), ex); + } + } + } + finally + { + try + { + if(useXA && ut != null) + { + if(rollback) + { + ut.rollback(); + } + else + { + ut.commit(); + } + } + if(useTx && !useXA) + { + if(rollback) + { + session.rollback(); + } + else + { + session.commit(); + } + } + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + throw new ServletException(e.getMessage(), e); + } + + QpidUtil.closeResources(messageProducer, session); + } + + resp.getOutputStream().println("Sent " + count + " messages with content '" + content + "'"); + resp.getOutputStream().flush(); + + int ackMode = Session.AUTO_ACKNOWLEDGE; + rollback = false; + + if(useXA) + { + ut.begin(); + } + + session = (useXA) ? connection.createSession(false, Session.AUTO_ACKNOWLEDGE) : connection.createSession(useTx, Session.AUTO_ACKNOWLEDGE); + messageConsumer = session.createConsumer(_responseQueue); + connection.start(); + + for(int i = 0; i < count; i++) + { + TextMessage message = (TextMessage)messageConsumer.receive(5000); + + if(message != null) + { + message.acknowledge(); + content = message.getText(); + + } + } + + startTime = System.currentTimeMillis() - startTime; + resp.getOutputStream().println("Received " + count + " messages with content '" + content + "'"); + resp.getOutputStream().println("Total process time " + startTime); + } + catch(Exception e) + { + rollback = true; + + if(useXA && ut != null) + { + try + { + ut.setRollbackOnly(); + } + catch(Exception ex) + { + _log.error(ex.getMessage(), ex); + throw new ServletException(ex.getMessage(), ex); + } + } + } + finally + { + if(useXA && ut != null) + { + try + { + if(rollback) + { + ut.rollback(); + } + else + { + ut.commit(); + } + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + throw new ServletException(e.getMessage(), e); + + } + } + + if(useTx && !useXA) + { + try + { + if(rollback) + { + session.rollback(); + } + else + { + session.commit(); + } + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + throw new ServletException(e.getMessage(), e); + } + } + + QpidUtil.closeResources(messageProducer, session); + } + } + +} + + diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/web/QpidTestServlet.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/web/QpidTestServlet.java index 11a61e762c..7526daa83d 100644 --- a/java/jca/example/src/main/java/org/apache/qpid/jca/example/web/QpidTestServlet.java +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/web/QpidTestServlet.java @@ -52,15 +52,16 @@ public class QpidTestServlet extends HttpServlet private static final int DEFAULT_COUNT = 1; private static final boolean DEFAULT_TOPIC = false; private static final boolean DEFAULT_XA = false; + private static final boolean DEFAULT_TX = false; private static final boolean DEFAULT_SAY_GOODBYE = true; @Resource(@jndi.scheme@="@qpid.xacf.jndi.name@") private ConnectionFactory _connectionFactory; - @Resource(@jndi.scheme@="HelloQueue") + @Resource(@jndi.scheme@="@qpid.hello.queue.jndi.name@") private Destination _queue; - @Resource(@jndi.scheme@="HelloTopic") + @Resource(@jndi.scheme@="@qpid.hello.topic.jndi.name@") private Destination _topic; @EJB @@ -82,6 +83,7 @@ public class QpidTestServlet extends HttpServlet UserTransaction ut = null; boolean useXA = false; boolean rollback = false; + boolean useTX = false; try { @@ -90,8 +92,10 @@ public class QpidTestServlet extends HttpServlet int count = (req.getParameter("count") == null) ? DEFAULT_COUNT : Integer.valueOf(req.getParameter("count")); boolean useTopic = (req.getParameter("useTopic") == null) ? DEFAULT_TOPIC : Boolean.valueOf(req.getParameter("useTopic")); useXA = (req.getParameter("useXA") == null) ? DEFAULT_XA : Boolean.valueOf(req.getParameter("useXA")); + useTX = (req.getParameter("useTX") == null) ? DEFAULT_TX : Boolean.valueOf(req.getParameter("useTX")); ctx = new InitialContext(); boolean sayGoodBye = (req.getParameter("sayGoodBye") == null) ? DEFAULT_SAY_GOODBYE : Boolean.valueOf(req.getParameter("sayGoodBye")); + useTX = (req.getParameter("useTX") == null) ? DEFAULT_TOPIC : Boolean.valueOf(req.getParameter("DEFAULT_TX")); _log.debug("Environment: "); _log.debug("Message content: " + content); @@ -122,7 +126,7 @@ public class QpidTestServlet extends HttpServlet } connection = _connectionFactory.createConnection(); - session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + session = connection.createSession(useTX, Session.AUTO_ACKNOWLEDGE); messageProducer = (useTopic) ? session.createProducer(_topic) : session.createProducer(_queue); for(int i = 0; i < count; i++) @@ -155,6 +159,19 @@ public class QpidTestServlet extends HttpServlet } } + if(useTX) + { + try + { + session.rollback(); + } + catch(Exception ex) + { + _log.error(ex.getMessage(), ex); + throw new ServletException(ex.getMessage(), ex); + } + } + _log.error(e.getMessage(), e); throw new ServletException(e.getMessage(), e); } @@ -181,12 +198,32 @@ public class QpidTestServlet extends HttpServlet } } + if(useTX && !useXA) + { + try + { + + if(rollback) + { + session.rollback(); + } + else + { + session.commit(); + } + } + catch(Exception e) + { + + _log.error(e.getMessage(), e); + throw new ServletException(e.getMessage(), e); + } + } + QpidUtil.closeResources(session, connection, ctx); } } - - } diff --git a/java/jca/src/main/java/org/apache/qpid/ra/ConnectionFactoryProperties.java b/java/jca/src/main/java/org/apache/qpid/ra/ConnectionFactoryProperties.java index a7b36bc98c..3bddfd80a4 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/ConnectionFactoryProperties.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/ConnectionFactoryProperties.java @@ -34,7 +34,7 @@ public class ConnectionFactoryProperties private boolean _hasBeenUpdated = false; - private String _clientID; + private String _clientId; private String _connectionURL; @@ -56,7 +56,7 @@ public class ConnectionFactoryProperties { _log.trace("getClientID()"); } - return _clientID; + return _clientId; } public void setClientId(final String clientID) @@ -66,7 +66,7 @@ public class ConnectionFactoryProperties _log.trace("setClientID(" + clientID + ")"); } _hasBeenUpdated = true; - this._clientID = clientID; + this._clientId = clientID; } public boolean isHasBeenUpdated() diff --git a/java/jca/src/main/java/org/apache/qpid/ra/QpidRAConnectionRequestInfo.java b/java/jca/src/main/java/org/apache/qpid/ra/QpidRAConnectionRequestInfo.java index c37a264ebc..779709839a 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/QpidRAConnectionRequestInfo.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/QpidRAConnectionRequestInfo.java @@ -45,7 +45,7 @@ public class QpidRAConnectionRequestInfo implements ConnectionRequestInfo private String _password; /** The client id */ - private String _clientID; + private String _clientId; /** The type */ private final int _type; @@ -76,13 +76,13 @@ public class QpidRAConnectionRequestInfo implements ConnectionRequestInfo final ConnectionURL connectionURL = ra.getDefaultAMQConnectionFactory().getConnectionURL() ; _userName = connectionURL.getUsername(); _password = connectionURL.getPassword(); - _clientID = connectionURL.getClientName(); + _clientId = connectionURL.getClientName(); } else { - _userName = ra.getDefaultUserName(); - _password = ra.getDefaultPassword(); - _clientID = ra.getClientId(); + _userName = ra.getUserName(); + _password = ra.getPassword(); + _clientId = ra.getClientId(); } this._type = type; _transacted = true; @@ -142,9 +142,9 @@ public class QpidRAConnectionRequestInfo implements ConnectionRequestInfo { _password = connectionURL.getPassword(); } - if (_clientID == null) + if (_clientId == null) { - _clientID = connectionURL.getClientName(); + _clientId = connectionURL.getClientName(); } } @@ -170,15 +170,15 @@ public class QpidRAConnectionRequestInfo implements ConnectionRequestInfo { if (_userName == null) { - _userName = ra.getDefaultUserName(); + _userName = ra.getUserName(); } if (_password == null) { - _password = ra.getDefaultPassword(); + _password = ra.getPassword(); } - if (_clientID == null) + if (_clientId == null) { - _clientID = ra.getClientId(); + _clientId = ra.getClientId(); } } } @@ -243,28 +243,28 @@ public class QpidRAConnectionRequestInfo implements ConnectionRequestInfo * Get the client id * @return The value */ - public String getClientID() + public String getClientId() { if (_log.isTraceEnabled()) { _log.trace("getClientID()"); } - return _clientID; + return _clientId; } /** * Set the client id * @param clientID The value */ - public void setClientID(final String clientID) + public void setClientId(final String clientID) { if (_log.isTraceEnabled()) { _log.trace("setClientID(" + clientID + ")"); } - this._clientID = clientID; + this._clientId = clientID; } /** @@ -321,7 +321,7 @@ public class QpidRAConnectionRequestInfo implements ConnectionRequestInfo { QpidRAConnectionRequestInfo you = (QpidRAConnectionRequestInfo)obj; return Util.compare(_userName, you.getUserName()) && Util.compare(_password, you.getPassword()) && - Util.compare(_clientID, you.getClientID()) && + Util.compare(_clientId, you.getClientId()) && _type == you.getType() && _transacted == you.isTransacted() && _acknowledgeMode == you.getAcknowledgeMode(); @@ -343,7 +343,7 @@ public class QpidRAConnectionRequestInfo implements ConnectionRequestInfo hash += 31 * hash + (_userName != null ? _userName.hashCode() : 0); hash += 31 * hash + (_password != null ? _password.hashCode() : 0); - hash += 31 * hash + (_clientID != null ? _clientID.hashCode() : 0); + hash += 31 * hash + (_clientId != null ? _clientId.hashCode() : 0); hash += 31 * hash + _type; hash += 31 * hash + (_transacted ? 1 : 0); hash += 31 * hash + _acknowledgeMode; @@ -356,6 +356,6 @@ public class QpidRAConnectionRequestInfo implements ConnectionRequestInfo { return "QpidRAConnectionRequestInfo[type=" + _type + ", transacted=" + _transacted + ", acknowledgeMode=" + _acknowledgeMode + - ", clientID=" + _clientID + ", userName=" + _userName + ((_password != null) ? ", password=********]" :"]"); + ", clientID=" + _clientId + ", userName=" + _userName + ((_password != null) ? ", password=********]" :"]"); } } diff --git a/java/jca/src/main/java/org/apache/qpid/ra/QpidRAManagedConnection.java b/java/jca/src/main/java/org/apache/qpid/ra/QpidRAManagedConnection.java index 53896d8872..eccf77aff2 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/QpidRAManagedConnection.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/QpidRAManagedConnection.java @@ -34,10 +34,11 @@ import java.util.concurrent.locks.ReentrantLock; import javax.jms.Connection; import javax.jms.ExceptionListener; import javax.jms.JMSException; +import javax.jms.QueueConnection; import javax.jms.ResourceAllocationException; import javax.jms.Session; -import javax.jms.QueueConnection; import javax.jms.TopicConnection; +import javax.jms.XAConnection; import javax.jms.XAQueueConnection; import javax.jms.XASession; import javax.jms.XATopicConnection; @@ -260,7 +261,20 @@ public class QpidRAManagedConnection implements ManagedConnection, ExceptionList } catch (JMSException e) { - _log.debug("Error closing session " + this, e); + _log.debug("Error closing XASession " + this, e); + } + + try + { + if(_session != null) + { + _session.close(); + } + + } + catch(JMSException e) + { + _log.error("Error closing Session " + this, e); } if (_connection != null) @@ -585,7 +599,7 @@ public class QpidRAManagedConnection implements ManagedConnection, ExceptionList */ protected Session getSession() throws JMSException { - if(_xaSession != null && !_mcf.getUseLocalTx()) + if(_xaSession != null && !_mcf.getUseLocalTx() && _inManagedTx) { if (_log.isTraceEnabled()) { @@ -761,107 +775,44 @@ public class QpidRAManagedConnection implements ManagedConnection, ExceptionList { if (_userName != null && _password != null) { - if(!transacted) - { - _connection = _mcf.getCleanAMQConnectionFactory().createXATopicConnection(_userName, _password); - } - else - { - _connection = _mcf.getCleanAMQConnectionFactory().createTopicConnection(_userName, _password); - } + _connection = _mcf.getCleanAMQConnectionFactory().createXATopicConnection(_userName, _password); } else { - if(!transacted) - { - _connection = _mcf.getDefaultAMQConnectionFactory().createXATopicConnection(); - } - else - { - _connection = _mcf.getDefaultAMQConnectionFactory().createTopicConnection(); - } + _connection = _mcf.getDefaultAMQConnectionFactory().createXATopicConnection(); } - if(!transacted) - { - _xaSession = ((XATopicConnection)_connection).createXATopicSession(); - } - else - { - _session = ((TopicConnection)_connection).createTopicSession(transacted, acknowledgeMode); - } + _xaSession = ((XATopicConnection)_connection).createXATopicSession(); + _session = ((TopicConnection)_connection).createTopicSession(transacted, acknowledgeMode); + } else if (_cri.getType() == QpidRAConnectionFactory.QUEUE_CONNECTION) { if (_userName != null && _password != null) { - if(!transacted) - { - _connection = _mcf.getCleanAMQConnectionFactory().createXAQueueConnection(_userName, _password); - } - else - { - _connection = _mcf.getCleanAMQConnectionFactory().createQueueConnection(_userName, _password); - } + _connection = _mcf.getCleanAMQConnectionFactory().createXAQueueConnection(_userName, _password); } else { - if(!transacted) - { - _connection = _mcf.getDefaultAMQConnectionFactory().createXAQueueConnection(); - } - else - { - _connection = _mcf.getDefaultAMQConnectionFactory().createQueueConnection(); - } + _connection = _mcf.getDefaultAMQConnectionFactory().createXAQueueConnection(); } - if(!transacted) - { - _xaSession = ((XAQueueConnection)_connection).createXAQueueSession(); + _xaSession = ((XAQueueConnection)_connection).createXAQueueSession(); + _session = ((QueueConnection)_connection).createQueueSession(transacted, acknowledgeMode); - } - else - { - _session = ((QueueConnection)_connection).createQueueSession(transacted, acknowledgeMode); - - } } else { if (_userName != null && _password != null) { - if(!transacted) - { - _connection = _mcf.getCleanAMQConnectionFactory().createXAConnection(_userName, _password); - } - else - { - _connection = _mcf.getCleanAMQConnectionFactory().createConnection(_userName, _password); - } - } - else - { - if(!transacted) - { - _connection = _mcf.getDefaultAMQConnectionFactory().createXAConnection(); - } - else - { - _connection = _mcf.getDefaultAMQConnectionFactory().createConnection(); - } - } - - if(!transacted) - { - _xaSession = ((XAQueueConnection)_connection).createXASession(); - + _connection = _mcf.getCleanAMQConnectionFactory().createXAConnection(_userName, _password); } else { - _session = ((QueueConnection)_connection).createSession(transacted, acknowledgeMode); - + _connection = _mcf.getDefaultAMQConnectionFactory().createXAConnection(); } + _xaSession = ((XAConnection)_connection).createXASession(); + _session = _connection.createSession(transacted, acknowledgeMode); } _connection.setExceptionListener(this); diff --git a/java/jca/src/main/java/org/apache/qpid/ra/QpidRAManagedConnectionFactory.java b/java/jca/src/main/java/org/apache/qpid/ra/QpidRAManagedConnectionFactory.java index 318485a7f2..8744a9deec 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/QpidRAManagedConnectionFactory.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/QpidRAManagedConnectionFactory.java @@ -365,12 +365,12 @@ public class QpidRAManagedConnectionFactory implements ManagedConnectionFactory, _mcfProperties.setSessionDefaultType(type); } - public String getClientID() + public String getClientId() { return _mcfProperties.getClientId(); } - public void setClientID(final String clientID) + public void setClientId(final String clientID) { _mcfProperties.setClientId(clientID); } diff --git a/java/jca/src/main/java/org/apache/qpid/ra/QpidRAProperties.java b/java/jca/src/main/java/org/apache/qpid/ra/QpidRAProperties.java index 21f7d2574f..69320575b0 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/QpidRAProperties.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/QpidRAProperties.java @@ -31,10 +31,8 @@ import org.slf4j.LoggerFactory; */ public class QpidRAProperties extends ConnectionFactoryProperties implements Serializable { - /** Serial version UID */ private static final long serialVersionUID = -4823893873707374791L; - /** The logger */ private static final Logger _log = LoggerFactory.getLogger(QpidRAProperties.class); private static final int DEFAULT_SETUP_ATTEMPTS = 10; @@ -45,16 +43,14 @@ public class QpidRAProperties extends ConnectionFactoryProperties implements Ser private long _setupInterval = DEFAULT_SETUP_INTERVAL; - /** Use Local TX instead of XA */ - private Boolean _localTx = false; - /** Class used to locate the Transaction Manager. */ private String _transactionManagerLocatorClass ; /** Method used to locate the TM */ private String _transactionManagerLocatorMethod ; - + private boolean _useConnectionPerHandler = true; + /** * Constructor */ @@ -66,34 +62,6 @@ public class QpidRAProperties extends ConnectionFactoryProperties implements Ser } } - /** - * Get the use XA flag - * @return The value - */ - public Boolean getUseLocalTx() - { - if (_log.isTraceEnabled()) - { - _log.trace("getUseLocalTx()"); - } - - return _localTx; - } - - /** - * Set the use XA flag - * @param localTx The value - */ - public void setUseLocalTx(final Boolean localTx) - { - if (_log.isTraceEnabled()) - { - _log.trace("setUseLocalTx(" + localTx + ")"); - } - - this._localTx = localTx; - } - public void setTransactionManagerLocatorClass(final String transactionManagerLocatorClass) { if (_log.isTraceEnabled()) @@ -174,10 +142,20 @@ public class QpidRAProperties extends ConnectionFactoryProperties implements Ser this._setupInterval = setupInterval; } + public boolean isUseConnectionPerHandler() + { + return _useConnectionPerHandler; + } + + public void setUseConnectionPerHandler(boolean connectionPerHandler) + { + this._useConnectionPerHandler = connectionPerHandler; + } + @Override public String toString() { - return "QpidRAProperties[localTx=" + _localTx + + return "QpidRAProperties[" + ", transactionManagerLocatorClass=" + _transactionManagerLocatorClass + ", transactionManagerLocatorMethod=" + _transactionManagerLocatorMethod + ", setupAttempts=" + _setupAttempts + diff --git a/java/jca/src/main/java/org/apache/qpid/ra/QpidRASession.java b/java/jca/src/main/java/org/apache/qpid/ra/QpidRASession.java index 081677ca4b..a72f51da51 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/QpidRASession.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/QpidRASession.java @@ -30,4 +30,6 @@ public interface QpidRASession public void start() throws JMSException; public void close() throws JMSException; + + public void closeSession() throws JMSException; } diff --git a/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionFactory.java b/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionFactory.java index cf28d5bba1..2747282a3c 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionFactory.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionFactory.java @@ -58,5 +58,5 @@ public interface QpidRASessionFactory extends Connection, TopicConnection, Queue * @param session The session * @throws JMSException for any error */ - void closeSession(QpidRASessionImpl session) throws JMSException; + void closeSession(QpidRASession session) throws JMSException; } diff --git a/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionFactoryImpl.java b/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionFactoryImpl.java index e2bc2d2008..f3253e1400 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionFactoryImpl.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionFactoryImpl.java @@ -567,7 +567,7 @@ public class QpidRASessionFactoryImpl implements QpidRASessionFactory, Reference _started = true; for (Iterator<QpidRASession> i = _sessions.iterator(); i.hasNext();) { - QpidRASessionImpl session = (QpidRASessionImpl)i.next(); + QpidRASession session = (QpidRASession)i.next(); session.start(); } } @@ -609,7 +609,7 @@ public class QpidRASessionFactoryImpl implements QpidRASessionFactory, Reference { for (Iterator<QpidRASession> i = _sessions.iterator(); i.hasNext();) { - QpidRASessionImpl session = (QpidRASessionImpl)i.next(); + QpidRASession session = (QpidRASession)i.next(); try { session.closeSession(); @@ -670,7 +670,7 @@ public class QpidRASessionFactoryImpl implements QpidRASessionFactory, Reference * @param session The session * @exception JMSException Thrown if an error occurs */ - public void closeSession(final QpidRASessionImpl session) throws JMSException + public void closeSession(final QpidRASession session) throws JMSException { if (_log.isTraceEnabled()) { @@ -679,7 +679,7 @@ public class QpidRASessionFactoryImpl implements QpidRASessionFactory, Reference synchronized (_sessions) { - _sessions.remove(session); + _sessions.clear(); } } @@ -742,7 +742,7 @@ public class QpidRASessionFactoryImpl implements QpidRASessionFactory, Reference QpidRAConnectionRequestInfo info = new QpidRAConnectionRequestInfo(sessionType); info.setUserName(_userName); info.setPassword(_password); - info.setClientID(_clientID); + info.setClientId(_clientID); info.setDefaults(_mcf.getDefaultAMQConnectionFactory().getConnectionURL()); if (_log.isTraceEnabled()) @@ -839,7 +839,7 @@ public class QpidRASessionFactoryImpl implements QpidRASessionFactory, Reference sessionType); info.setUserName(_userName); info.setPassword(_password); - info.setClientID(_clientID); + info.setClientId(_clientID); info.setDefaults(_mcf.getDefaultAMQConnectionFactory().getConnectionURL()); if (_log.isTraceEnabled()) diff --git a/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionImpl.java b/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionImpl.java index fdd4888a3d..c4cfeaba48 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionImpl.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/QpidRASessionImpl.java @@ -1446,7 +1446,7 @@ public class QpidRASessionImpl implements Session, QueueSession, TopicSession, X * Close session * @exception JMSException Thrown if an error occurs */ - void closeSession() throws JMSException + public void closeSession() throws JMSException { final QpidRAManagedConnection mc = this._mc; if (mc != null) diff --git a/java/jca/src/main/java/org/apache/qpid/ra/QpidResourceAdapter.java b/java/jca/src/main/java/org/apache/qpid/ra/QpidResourceAdapter.java index 363af1bbcd..96fa83ceef 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/QpidResourceAdapter.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/QpidResourceAdapter.java @@ -38,8 +38,6 @@ import javax.resource.spi.work.WorkManager; import javax.transaction.TransactionManager; import javax.transaction.xa.XAResource; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.apache.qpid.client.AMQConnection; import org.apache.qpid.client.AMQConnectionFactory; import org.apache.qpid.client.AMQConnectionURL; @@ -47,6 +45,8 @@ import org.apache.qpid.client.XAConnectionImpl; import org.apache.qpid.ra.inflow.QpidActivation; import org.apache.qpid.ra.inflow.QpidActivationSpec; import org.apache.qpid.url.URLSyntaxException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The resource adapter for Qpid @@ -54,43 +54,22 @@ import org.apache.qpid.url.URLSyntaxException; */ public class QpidResourceAdapter implements ResourceAdapter, Serializable { - /** - * - */ private static final long serialVersionUID = -2446231446818098726L; - /** - * The logger - */ - private static final Logger _log = LoggerFactory.getLogger(QpidResourceAdapter.class); + private static final transient Logger _log = LoggerFactory.getLogger(QpidResourceAdapter.class); - /** - * The bootstrap context - */ private BootstrapContext _ctx; - /** - * The resource adapter properties - */ private final QpidRAProperties _raProperties; - /** - * Have the factory been configured - */ private final AtomicBoolean _configured; - /** - * The activations by activation spec - */ private final Map<ActivationSpec, QpidActivation> _activations; private AMQConnectionFactory _defaultAMQConnectionFactory; private TransactionManager _tm; - /** - * Constructor - */ public QpidResourceAdapter() { if (_log.isTraceEnabled()) @@ -223,65 +202,6 @@ public class QpidResourceAdapter implements ResourceAdapter, Serializable _log.info("Qpid resource adapter stopped"); } - /** - * Get the user name - * - * @return The value - */ - public String getDefaultUserName() - { - if (_log.isTraceEnabled()) - { - _log.trace("getUserName()"); - } - - return _raProperties.getUserName(); - } - - /** - * Set the user name - * - * @param userName The value - */ - public void setDefaultUserName(final String userName) - { - if (_log.isTraceEnabled()) - { - _log.trace("setUserName(" + userName + ")"); - } - - _raProperties.setUserName(userName); - } - - /** - * Get the password - * - * @return The value - */ - public String getDefaultPassword() - { - if (_log.isTraceEnabled()) - { - _log.trace("getPassword()"); - } - - return _raProperties.getPassword(); - } - - /** - * Set the password - * - * @param password The value - */ - public void setDefaultPassword(final String password) - { - if (_log.isTraceEnabled()) - { - _log.trace("setPassword(****)"); - } - - _raProperties.setPassword(password); - } /** * Get the client ID @@ -403,6 +323,26 @@ public class QpidResourceAdapter implements ResourceAdapter, Serializable _raProperties.setPath(path); } + public String getUserName() + { + return _raProperties.getUserName(); + } + + public void setUserName(String userName) + { + _raProperties.setUserName(userName); + } + + public String getPassword() + { + return _raProperties.getPassword(); + } + + public void setPassword(String password) + { + _raProperties.setPassword(password); + } + /** * Get the connection url * @@ -493,14 +433,14 @@ public class QpidResourceAdapter implements ResourceAdapter, Serializable * * @return The value */ - public Boolean getUseLocalTx() + public Boolean isUseLocalTx() { if (_log.isTraceEnabled()) { _log.trace("getUseLocalTx()"); } - return _raProperties.getUseLocalTx(); + return _raProperties.isUseLocalTx(); } /** @@ -553,7 +493,27 @@ public class QpidResourceAdapter implements ResourceAdapter, Serializable } _raProperties.setSetupInterval(interval); } + + public Boolean isUseConnectionPerHandler() + { + if (_log.isTraceEnabled()) + { + _log.trace("isConnectionPerHandler()"); + } + + return _raProperties.isUseConnectionPerHandler(); + } + public void setUseConnectionPerHandler(Boolean connectionPerHandler) + { + if (_log.isTraceEnabled()) + { + _log.trace("setConnectionPerHandler(" + connectionPerHandler + ")"); + } + + _raProperties.setUseConnectionPerHandler(connectionPerHandler); + } + /** * Indicates whether some other object is "equal to" this one. * @@ -720,9 +680,10 @@ public class QpidResourceAdapter implements ResourceAdapter, Serializable return map; } - private void locateTM() + private void locateTM() throws ResourceAdapterInternalException { - if(_raProperties.getTransactionManagerLocatorClass() != null && _raProperties.getTransactionManagerLocatorMethod() != null) + if(_raProperties.getTransactionManagerLocatorClass() != null + && _raProperties.getTransactionManagerLocatorMethod() != null) { String locatorClasses[] = _raProperties.getTransactionManagerLocatorClass().split(";"); @@ -742,8 +703,8 @@ public class QpidResourceAdapter implements ResourceAdapter, Serializable if (_tm == null) { - _log.warn("It wasn't possible to lookup a Transaction Manager through the configured properties TransactionManagerLocatorClass and TransactionManagerLocatorMethod"); - _log.warn("Qpid Resource Adapter won't be able to set and verify transaction timeouts in certain cases."); + _log.error("It was not possible to locate javax.transaction.TransactionManager via the RA properties TransactionManagerLocatorClass and TransactionManagerLocatorMethod"); + throw new ResourceAdapterInternalException("Could not locate javax.transaction.TransactionManager"); } else { @@ -802,6 +763,7 @@ public class QpidResourceAdapter implements ResourceAdapter, Serializable final String client = (clientID != null ? clientID : "") ; final String newurl = AMQConnectionURL.AMQ_PROTOCOL + "://" + username +":" + password + "@" + client + "/" + path + '?' + AMQConnectionURL.OPTIONS_BROKERLIST + "='tcp://" + host + ':' + port + '\'' ; + if (_log.isDebugEnabled()) { _log.debug("Initialising connectionURL to " + newurl) ; diff --git a/java/jca/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxy.java b/java/jca/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxy.java index 41242fefae..a948948d6a 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxy.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxy.java @@ -77,17 +77,17 @@ public class QpidConnectionFactoryProxy implements Externalizable, Referenceable public void writeExternal(ObjectOutput out) throws IOException { - if (_delegate == null) - { - _log.error("Null Destination "); - throw new IOException("Null ConnectionFactory!"); - } try { + if(_delegate == null) + { + getReference(); + } + out.writeObject(((Referenceable) _delegate).getReference()); } - catch (NamingException e) + catch (Exception e) { _log.error("Failed to dereference ConnectionFactory " + e.getMessage(), e); throw new IOException("Failed to dereference ConnectionFactory: " + e.getMessage()); @@ -137,7 +137,20 @@ public class QpidConnectionFactoryProxy implements Externalizable, Referenceable */ public Connection createConnection() throws JMSException { - return _delegate.createConnection(); + try + { + if(_delegate == null) + { + getReference(); + } + + return _delegate.createConnection(); + } + catch(Exception e) + { + throw new JMSException(e.getMessage()); + } + } /** diff --git a/java/jca/src/main/java/org/apache/qpid/ra/admin/QpidQueueImpl.java b/java/jca/src/main/java/org/apache/qpid/ra/admin/QpidQueueImpl.java index 417849fc5c..162099d1ee 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/admin/QpidQueueImpl.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/admin/QpidQueueImpl.java @@ -21,25 +21,15 @@ package org.apache.qpid.ra.admin; import java.io.Externalizable; -import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInput; -import java.io.ObjectInputStream; import java.io.ObjectOutput; -import java.io.ObjectOutputStream; -import java.util.Hashtable; -import javax.naming.Context; -import javax.naming.Name; import javax.naming.NamingException; -import javax.naming.RefAddr; import javax.naming.Reference; import javax.naming.StringRefAddr; -import javax.naming.spi.ObjectFactory; import org.apache.qpid.client.AMQQueue; -import org.apache.qpid.ra.admin.AdminObjectFactory; public class QpidQueueImpl extends AMQQueue implements QpidQueue, Externalizable { @@ -101,19 +91,4 @@ public class QpidQueueImpl extends AMQQueue implements QpidQueue, Externalizable out.writeObject(this._url); } - //TODO move to tests - public static void main(String[] args) throws Exception - { - QpidQueueImpl q = new QpidQueueImpl(); - q.setDestinationAddress("hello.Queue;{create:always, node:{type:queue, x-declare:{auto-delete:true}}}"); - ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream("queue.out")); - os.writeObject(q); - os.close(); - - - ObjectInputStream is = new ObjectInputStream(new FileInputStream("queue.out")); - q = (QpidQueueImpl)is.readObject(); - System.out.println(q); - - } } diff --git a/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidActivation.java b/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidActivation.java index 57edec8eee..2327512a62 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidActivation.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidActivation.java @@ -20,114 +20,28 @@ */ package org.apache.qpid.ra.inflow; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.atomic.AtomicBoolean; -import javax.jms.Connection; -import javax.jms.Destination; -import javax.jms.ExceptionListener; -import javax.jms.JMSException; -import javax.jms.Message; -import javax.jms.MessageListener; -import javax.jms.Queue; -import javax.jms.Session; -import javax.jms.Topic; -import javax.naming.Context; -import javax.naming.InitialContext; import javax.resource.ResourceException; import javax.resource.spi.endpoint.MessageEndpointFactory; import javax.resource.spi.work.Work; -import javax.resource.spi.work.WorkManager; +import org.apache.qpid.ra.QpidResourceAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.apache.qpid.AMQException; -import org.apache.qpid.client.AMQConnection; -import org.apache.qpid.client.AMQConnectionFactory; -import org.apache.qpid.client.AMQDestination; -import org.apache.qpid.client.XAConnectionImpl; -import org.apache.qpid.protocol.AMQConstant; -import org.apache.qpid.ra.QpidResourceAdapter; -import org.apache.qpid.ra.Util; - /** * The activation. * */ -public class QpidActivation implements ExceptionListener +public class QpidActivation extends QpidExceptionHandler { - /** - * The logger - */ private static final Logger _log = LoggerFactory.getLogger(QpidActivation.class); - /** - * The onMessage method - */ - public static final Method ONMESSAGE; - - /** - * The resource adapter - */ - private final QpidResourceAdapter _ra; - - /** - * The activation spec - */ - private final QpidActivationSpec _spec; - - /** - * The message endpoint factory - */ - private final MessageEndpointFactory _endpointFactory; - - /** - * Whether delivery is active - */ - private final AtomicBoolean _deliveryActive = new AtomicBoolean(false); - - /** - * The destination type - */ - private boolean _isTopic = false; - - /** - * Is the delivery transacted - */ - private boolean _isDeliveryTransacted; - - private Destination _destination; - - /** - * The connection - */ - private Connection _connection; - private final List<QpidMessageHandler> _handlers = new ArrayList<QpidMessageHandler>(); - private AMQConnectionFactory _factory; - - // Whether we are in the failure recovery loop - private AtomicBoolean _inFailure = new AtomicBoolean(false); - - //Whether or not we have completed activating - private AtomicBoolean _activated = new AtomicBoolean(false); - - static - { - try - { - ONMESSAGE = MessageListener.class.getMethod("onMessage", new Class[] { Message.class }); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - + /** * Constructor * @@ -140,97 +54,8 @@ public class QpidActivation implements ExceptionListener final MessageEndpointFactory endpointFactory, final QpidActivationSpec spec) throws ResourceException { - if (_log.isTraceEnabled()) - { - _log.trace("constructor(" + ra + ", " + endpointFactory + ", " + spec + ")"); - } - - this._ra = ra; - this._endpointFactory = endpointFactory; - this._spec = spec; - try - { - _isDeliveryTransacted = endpointFactory.isDeliveryTransacted(QpidActivation.ONMESSAGE); - } - catch (Exception e) - { - throw new ResourceException(e); - } - } - - /** - * Get the activation spec - * - * @return The value - */ - public QpidActivationSpec getActivationSpec() - { - if (_log.isTraceEnabled()) - { - _log.trace("getActivationSpec()"); - } - - return _spec; - } - - /** - * Get the message endpoint factory - * - * @return The value - */ - public MessageEndpointFactory getMessageEndpointFactory() - { - if (_log.isTraceEnabled()) - { - _log.trace("getMessageEndpointFactory()"); - } - - return _endpointFactory; - } - - /** - * Get whether delivery is transacted - * - * @return The value - */ - public boolean isDeliveryTransacted() - { - if (_log.isTraceEnabled()) - { - _log.trace("isDeliveryTransacted()"); - } - - return _isDeliveryTransacted; - } - - /** - * Get the work manager - * - * @return The value - */ - public WorkManager getWorkManager() - { - if (_log.isTraceEnabled()) - { - _log.trace("getWorkManager()"); - } - - return _ra.getWorkManager(); - } - - /** - * Is the destination a topic - * - * @return The value - */ - public boolean isTopic() - { - if (_log.isTraceEnabled()) - { - _log.trace("isTopic()"); - } - - return _isTopic; + super(ra, spec, endpointFactory); + } /** @@ -267,70 +92,62 @@ public class QpidActivation implements ExceptionListener * * @throws Exception Thrown if an error occurs */ - protected synchronized void setup() throws Exception + public synchronized void setup() throws Exception { _log.debug("Setting up " + _spec); - setupCF(); - + setupCF(); setupDestination(); - final AMQConnection amqConnection ; - final boolean useLocalTx = _spec.isUseLocalTx() ; - final boolean isXA = _isDeliveryTransacted && !useLocalTx ; - - if (isXA) + + if(!_spec.isUseConnectionPerHandler()) { - amqConnection = (XAConnectionImpl)_factory.createXAConnection() ; + setupConnection(); + _connection.setExceptionListener(this); } - else - { - amqConnection = (AMQConnection)_factory.createConnection() ; - } - - amqConnection.setExceptionListener(this) ; - + for (int i = 0; i < _spec.getMaxSession(); i++) { - Session session = null; - - try - { - if (isXA) - { - session = _ra.createXASession((XAConnectionImpl)amqConnection) ; - } - else - { - session = _ra.createSession((AMQConnection)amqConnection, - _spec.getAcknowledgeModeInt(), - useLocalTx, - _spec.getPrefetchLow(), - _spec.getPrefetchHigh()); - } - - _log.debug("Using session " + Util.asString(session)); - QpidMessageHandler handler = new QpidMessageHandler(this, _ra.getTM(), session); - handler.setup(); - _handlers.add(handler); - } - catch (Exception e) - { - try - { - amqConnection.close() ; - } - catch (Exception e2) - { - _log.trace("Ignored error closing connection", e2); - } - - throw e; - } + try + { + QpidMessageHandler handler = null; + + if(_spec.isUseConnectionPerHandler()) + { + handler = new QpidMessageHandler(_ra, _spec, _endpointFactory, _ra.getTM()); + } + else + { + handler = new QpidMessageHandler(_ra, _spec, _endpointFactory, _ra.getTM(), _connection); + } + + handler.start(); + _handlers.add(handler); + } + catch(Exception e) + { + try + { + if(_connection != null) + { + this._connection.close(); + } + } + catch (Exception e2) + { + _log.trace("Ignored error closing connection", e2); + } + + throw e; + + } + + } + + if(!_spec.isUseConnectionPerHandler()) + { + this._connection.start(); + _activated.set(true); } - amqConnection.start() ; - this._connection = amqConnection ; - _activated.set(true); - _log.debug("Setup complete " + this); } @@ -340,136 +157,17 @@ public class QpidActivation implements ExceptionListener protected synchronized void teardown() { _log.debug("Tearing down " + _spec); - - try - { - if (_connection != null) - { - _connection.stop(); - } - } - catch (Throwable t) - { - _log.debug("Error stopping connection " + Util.asString(_connection), t); - } + + super.teardown(); for (QpidMessageHandler handler : _handlers) { - handler.teardown(); + handler.stop(); } - try - { - if (_connection != null) - { - _connection.close(); - } - } - catch (Throwable t) - { - _log.debug("Error closing connection " + Util.asString(_connection), t); - } - if (_spec.isHasBeenUpdated()) - { - _factory = null; - } _log.debug("Tearing down complete " + this); } - protected void setupCF() throws Exception - { - if (_spec.isHasBeenUpdated()) - { - _factory = _ra.createAMQConnectionFactory(_spec); - } - else - { - _factory = _ra.getDefaultAMQConnectionFactory(); - } - } - - public Destination getDestination() - { - return _destination; - } - - protected void setupDestination() throws Exception - { - - String destinationName = _spec.getDestination(); - String destinationTypeString = _spec.getDestinationType(); - - if (_spec.isUseJNDI()) - { - Context ctx = new InitialContext(); - _log.debug("Using context " + ctx.getEnvironment() + " for " + _spec); - if (_log.isTraceEnabled()) - { - _log.trace("setupDestination(" + ctx + ")"); - } - - if (destinationTypeString != null && !destinationTypeString.trim().equals("")) - { - _log.debug("Destination type defined as " + destinationTypeString); - - Class<? extends Destination> destinationType; - if (Topic.class.getName().equals(destinationTypeString)) - { - destinationType = Topic.class; - _isTopic = true; - } - else - { - destinationType = Queue.class; - } - - _log.debug("Retrieving destination " + destinationName + - " of type " + - destinationType.getName()); - _destination = Util.lookup(ctx, destinationName, destinationType); - - } - else - { - _log.debug("Destination type not defined"); - _log.debug("Retrieving destination " + destinationName + - " of type " + - Destination.class.getName()); - - _destination = Util.lookup(ctx, destinationName, AMQDestination.class); - _isTopic = !(_destination instanceof Queue) ; - } - } - else - { - _destination = (AMQDestination)AMQDestination.createDestination(_spec.getDestination()); - if (destinationTypeString != null && !destinationTypeString.trim().equals("")) - { - _log.debug("Destination type defined as " + destinationTypeString); - final boolean match ; - if (Topic.class.getName().equals(destinationTypeString)) - { - match = (_destination instanceof Topic) ; - _isTopic = true; - } - else - { - match = (_destination instanceof Queue) ; - } - if (!match) - { - throw new ClassCastException("Expected destination of type " + destinationTypeString + " but created destination " + _destination) ; - } - } - else - { - _isTopic = !(_destination instanceof Queue) ; - } - } - - _log.debug("Got destination " + _destination + " from " + destinationName); - } - /** * Get a string representation * @@ -492,94 +190,7 @@ public class QpidActivation implements ExceptionListener return buffer.toString(); } - public void onException(final JMSException jmse) - { - if(_activated.get()) - { - handleFailure(jmse) ; - } - else - { - _log.warn("Received JMSException: " + jmse + " while endpoint was not activated."); - } - } - - /** - * Handles any failure by trying to reconnect - * - * @param failure the reason for the failure - */ - public void handleFailure(Throwable failure) - { - if(doesNotExist(failure)) - { - _log.info("awaiting topic/queue creation " + getActivationSpec().getDestination()); - } - else - { - _log.warn("Failure in Qpid activation " + _spec, failure); - } - int reconnectCount = 0; - int setupAttempts = _spec.getSetupAttempts(); - long setupInterval = _spec.getSetupInterval(); - - // Only enter the failure loop once - if (_inFailure.getAndSet(true)) - return; - try - { - while (_deliveryActive.get() && (setupAttempts == -1 || reconnectCount < setupAttempts)) - { - teardown(); - - try - { - Thread.sleep(setupInterval); - } - catch (InterruptedException e) - { - _log.debug("Interrupted trying to reconnect " + _spec, e); - break; - } - - _log.info("Attempting to reconnect " + _spec); - try - { - setup(); - _log.info("Reconnected with Qpid"); - break; - } - catch (Throwable t) - { - if(doesNotExist(failure)) - { - _log.info("awaiting topic/queue creation " + getActivationSpec().getDestination()); - } - else - { - _log.error("Unable to reconnect " + _spec, t); - } - } - ++reconnectCount; - } - } - finally - { - // Leaving failure recovery loop - _inFailure.set(false); - } - } - - /** - * Check to see if the failure represents a missing endpoint - * @param failure The failure. - * @return true if it represents a missing endpoint, false otherwise - */ - private boolean doesNotExist(final Throwable failure) - { - return (failure instanceof AMQException) && (((AMQException)failure).getErrorCode() == AMQConstant.NOT_FOUND) ; - } - + /** * Handles the setup */ diff --git a/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidActivationSpec.java b/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidActivationSpec.java index 5f4e2dcf6b..3d9a88adb5 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidActivationSpec.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidActivationSpec.java @@ -28,10 +28,10 @@ import javax.resource.spi.ActivationSpec; import javax.resource.spi.InvalidPropertyException; import javax.resource.spi.ResourceAdapter; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.apache.qpid.ra.ConnectionFactoryProperties; import org.apache.qpid.ra.QpidResourceAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The activation spec @@ -88,6 +88,8 @@ public class QpidActivationSpec extends ConnectionFactoryProperties implements A // undefined by default, default is specified at the RA level in QpidRAProperties private Long _setupInterval; + private Boolean _useConnectionPerHandler; + /** * Constructor */ @@ -544,6 +546,16 @@ public class QpidActivationSpec extends ConnectionFactoryProperties implements A this._setupInterval = setupInterval; } + public Boolean isUseConnectionPerHandler() + { + return (_useConnectionPerHandler == null) ? _ra.isUseConnectionPerHandler() : _useConnectionPerHandler; + } + + public void setUseConnectionPerHandler(Boolean connectionPerHandler) + { + this._useConnectionPerHandler = connectionPerHandler; + } + /** * Validate * @exception InvalidPropertyException Thrown if a validation exception occurs @@ -561,6 +573,7 @@ public class QpidActivationSpec extends ConnectionFactoryProperties implements A } } + /** * Get a string representation * @return The value @@ -573,23 +586,30 @@ public class QpidActivationSpec extends ConnectionFactoryProperties implements A buffer.append("ra=").append(_ra); buffer.append(" destination=").append(_destination); buffer.append(" destinationType=").append(_destinationType); + if (_messageSelector != null) { buffer.append(" selector=").append(_messageSelector); } + buffer.append(" ack=").append(getAcknowledgeMode()); buffer.append(" durable=").append(_subscriptionDurability); buffer.append(" clientID=").append(getClientId()); + if (_subscriptionName != null) { buffer.append(" subscription=").append(_subscriptionName); } + buffer.append(" user=").append(getUserName()); + if (getPassword() != null) { - buffer.append(" password=").append("****"); + buffer.append(" password=").append("********"); } + buffer.append(" maxSession=").append(_maxSession); + if (_prefetchLow != null) { buffer.append(" prefetchLow=").append(_prefetchLow); @@ -598,7 +618,10 @@ public class QpidActivationSpec extends ConnectionFactoryProperties implements A { buffer.append(" prefetchHigh=").append(_prefetchHigh); } + + buffer.append(" connectionPerHandler=").append(isUseConnectionPerHandler()); buffer.append(')'); + return buffer.toString(); } } diff --git a/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidExceptionHandler.java b/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidExceptionHandler.java new file mode 100644 index 0000000000..8775362eb5 --- /dev/null +++ b/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidExceptionHandler.java @@ -0,0 +1,339 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.ra.inflow; + +import java.lang.reflect.Method; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.jms.ExceptionListener; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.Queue; +import javax.jms.Topic; +import javax.jms.XAConnectionFactory; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.resource.ResourceException; +import javax.resource.spi.endpoint.MessageEndpointFactory; + +import org.apache.qpid.AMQException; +import org.apache.qpid.client.AMQDestination; +import org.apache.qpid.protocol.AMQConstant; +import org.apache.qpid.ra.QpidResourceAdapter; +import org.apache.qpid.ra.Util; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class QpidExceptionHandler implements ExceptionListener +{ + private static final Logger _log = LoggerFactory.getLogger(QpidExceptionHandler.class); + + public static final Method ONMESSAGE; + + protected final MessageEndpointFactory _endpointFactory; + + protected Connection _connection; + + protected ConnectionFactory _factory; + + protected Destination _destination; + + protected final QpidResourceAdapter _ra; + + protected final QpidActivationSpec _spec; + + protected boolean _isDeliveryTransacted; + + protected final AtomicBoolean _deliveryActive = new AtomicBoolean(false); + + protected boolean _isTopic = false; + + // Whether we are in the failure recovery loop + protected AtomicBoolean _inFailure = new AtomicBoolean(false); + + //Whether or not we have completed activating + protected AtomicBoolean _activated = new AtomicBoolean(false); + + static + { + try + { + ONMESSAGE = MessageListener.class.getMethod("onMessage", new Class[] { Message.class }); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + + public abstract void setup() throws Exception; + public abstract void start() throws Exception; + public abstract void stop(); + + protected QpidExceptionHandler(QpidResourceAdapter ra, + QpidActivationSpec spec, + MessageEndpointFactory endpointFactory) throws ResourceException + { + this._ra = ra; + this._spec = spec; + this._endpointFactory = endpointFactory; + + try + { + _isDeliveryTransacted = endpointFactory.isDeliveryTransacted(QpidActivation.ONMESSAGE); + } + catch (Exception e) + { + throw new ResourceException(e); + } + + + } + + public void onException(JMSException e) + { + if(_activated.get()) + { + handleFailure(e) ; + } + else + { + _log.warn("Received JMSException: " + e + " while endpoint was not activated."); + } + } + + /** + * Handles any failure by trying to reconnect + * + * @param failure the reason for the failure + */ + public void handleFailure(Throwable failure) + { + if(doesNotExist(failure)) + { + _log.info("awaiting topic/queue creation " + _spec.getDestination()); + } + else + { + _log.warn("Failure in Qpid activation " + _spec, failure); + } + int reconnectCount = 0; + int setupAttempts = _spec.getSetupAttempts(); + long setupInterval = _spec.getSetupInterval(); + + // Only enter the failure loop once + if (_inFailure.getAndSet(true)) + return; + try + { + while (_deliveryActive.get() && (setupAttempts == -1 || reconnectCount < setupAttempts)) + { + teardown(); + + try + { + Thread.sleep(setupInterval); + } + catch (InterruptedException e) + { + _log.debug("Interrupted trying to reconnect " + _spec, e); + break; + } + + _log.info("Attempting to reconnect " + _spec); + try + { + setup(); + _log.info("Reconnected with Qpid"); + break; + } + catch (Throwable t) + { + if(doesNotExist(failure)) + { + _log.info("awaiting topic/queue creation " + _spec.getDestination()); + } + else + { + _log.error("Unable to reconnect " + _spec, t); + } + } + ++reconnectCount; + } + } + finally + { + // Leaving failure recovery loop + _inFailure.set(false); + } + } + + /** + * Check to see if the failure represents a missing endpoint + * @param failure The failure. + * @return true if it represents a missing endpoint, false otherwise + */ + protected boolean doesNotExist(final Throwable failure) + { + return (failure instanceof AMQException) && (((AMQException)failure).getErrorCode() == AMQConstant.NOT_FOUND) ; + } + + protected boolean isXA() + { + return _isDeliveryTransacted && !_spec.isUseLocalTx(); + } + + protected void setupConnection() throws Exception + { + this._connection = (isXA()) ? ((XAConnectionFactory)_factory).createXAConnection() : _factory.createConnection(); + } + + protected synchronized void teardown() + { + _log.debug("Tearing down " + _spec); + + try + { + if (_connection != null) + { + _connection.stop(); + } + } + catch (Throwable t) + { + _log.debug("Error stopping connection " + Util.asString(_connection), t); + } + + try + { + if (_connection != null) + { + _connection.close(); + } + } + catch (Throwable t) + { + _log.debug("Error closing connection " + Util.asString(_connection), t); + } + if (_spec.isHasBeenUpdated()) + { + _factory = null; + } + _log.debug("Tearing down complete " + this); + } + + protected void setupCF() throws Exception + { + if (_spec.isHasBeenUpdated()) + { + _factory = _ra.createAMQConnectionFactory(_spec); + } + else + { + _factory = _ra.getDefaultAMQConnectionFactory(); + } + } + + protected void setupDestination() throws Exception + { + + String destinationName = _spec.getDestination(); + String destinationTypeString = _spec.getDestinationType(); + + if (_spec.isUseJNDI()) + { + Context ctx = new InitialContext(); + _log.debug("Using context " + ctx.getEnvironment() + " for " + _spec); + if (_log.isTraceEnabled()) + { + _log.trace("setupDestination(" + ctx + ")"); + } + + if (destinationTypeString != null && !destinationTypeString.trim().equals("")) + { + _log.debug("Destination type defined as " + destinationTypeString); + + Class<? extends Destination> destinationType; + if (Topic.class.getName().equals(destinationTypeString)) + { + destinationType = Topic.class; + _isTopic = true; + } + else + { + destinationType = Queue.class; + } + + _log.debug("Retrieving destination " + destinationName + + " of type " + + destinationType.getName()); + _destination = Util.lookup(ctx, destinationName, destinationType); + + } + else + { + _log.debug("Destination type not defined"); + _log.debug("Retrieving destination " + destinationName + + " of type " + + Destination.class.getName()); + + _destination = Util.lookup(ctx, destinationName, AMQDestination.class); + _isTopic = !(_destination instanceof Queue) ; + } + } + else + { + _destination = (AMQDestination)AMQDestination.createDestination(_spec.getDestination()); + + if (destinationTypeString != null && !destinationTypeString.trim().equals("")) + { + _log.debug("Destination type defined as " + destinationTypeString); + final boolean match ; + if (Topic.class.getName().equals(destinationTypeString)) + { + match = (_destination instanceof Topic) ; + _isTopic = true; + } + else + { + match = (_destination instanceof Queue) ; + } + if (!match) + { + throw new ClassCastException("Expected destination of type " + destinationTypeString + " but created destination " + _destination) ; + } + } + else + { + _isTopic = !(_destination instanceof Queue) ; + } + } + + _log.debug("Got destination " + _destination + " from " + destinationName); + } + + + +} diff --git a/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidMessageHandler.java b/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidMessageHandler.java index 473efab31f..a02adf0dad 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidMessageHandler.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/inflow/QpidMessageHandler.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.ra.inflow; +import javax.jms.Connection; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageConsumer; @@ -35,6 +36,9 @@ import javax.transaction.Status; import javax.transaction.TransactionManager; import javax.transaction.xa.XAResource; +import org.apache.qpid.client.AMQConnection; +import org.apache.qpid.client.XAConnectionImpl; +import org.apache.qpid.ra.QpidResourceAdapter; import org.apache.qpid.ra.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,82 +47,100 @@ import org.slf4j.LoggerFactory; * The message handler * */ -public class QpidMessageHandler implements MessageListener +public class QpidMessageHandler extends QpidExceptionHandler implements MessageListener { - /** - * The logger - */ private static final Logger _log = LoggerFactory.getLogger(QpidMessageHandler.class); - /** - * The session - */ - private final Session _session; - private MessageConsumer _consumer; - /** - * The endpoint - */ private MessageEndpoint _endpoint; - private final QpidActivation _activation; - - private boolean _useLocalTx; - - private boolean _transacted; + private Session _session; private final TransactionManager _tm; - public QpidMessageHandler(final QpidActivation activation, - final TransactionManager tm, - final Session session) + public QpidMessageHandler(final QpidResourceAdapter ra, + final QpidActivationSpec spec, + final MessageEndpointFactory endpointFactory, + final TransactionManager tm, + final Connection connection) throws ResourceException { - this._activation = activation; - this._session = session; + super(ra, spec, endpointFactory); this._tm = tm; + this._connection = connection; } - + + public QpidMessageHandler(final QpidResourceAdapter ra, + final QpidActivationSpec spec, + final MessageEndpointFactory endpointFactory, + final TransactionManager tm) throws ResourceException + { + super(ra, spec, endpointFactory); + this._tm = tm; + } + public void setup() throws Exception { if (_log.isTraceEnabled()) { _log.trace("setup()"); } - - QpidActivationSpec spec = _activation.getActivationSpec(); - String selector = spec.getMessageSelector(); - + + setupCF(); + setupDestination(); + String selector = _spec.getMessageSelector(); + + if(_spec.isUseConnectionPerHandler()) + { + setupConnection(); + _connection.setExceptionListener(this); + } + + if(isXA()) + { + _session = _ra.createXASession((XAConnectionImpl)_connection); + } + else + { + _session = _ra.createSession((AMQConnection)_connection, + _spec.getAcknowledgeModeInt(), + _spec.isUseLocalTx(), + _spec.getPrefetchLow(), + _spec.getPrefetchHigh()); + } // Create the message consumer - if (_activation.isTopic()) + if (_isTopic) { - final Topic topic = (Topic) _activation.getDestination(); - final String subscriptionName = spec.getSubscriptionName(); - if (spec.isSubscriptionDurable()) - _consumer = _session.createDurableSubscriber(topic, subscriptionName, selector, false); + final Topic topic = (Topic) _destination; + final String subscriptionName = _spec.getSubscriptionName(); + + if (_spec.isSubscriptionDurable()) + { + _consumer = _session.createDurableSubscriber(topic, subscriptionName, selector, false); + } else - _consumer = _session.createConsumer(topic, selector) ; + { + _consumer = _session.createConsumer(topic, selector) ; + } } else { - final Queue queue = (Queue) _activation.getDestination(); + final Queue queue = (Queue) _destination; _consumer = _session.createConsumer(queue, selector); } - // Create the endpoint, if we are transacted pass the session so it is enlisted, unless using Local TX - MessageEndpointFactory endpointFactory = _activation.getMessageEndpointFactory(); - _useLocalTx = _activation.getActivationSpec().isUseLocalTx(); - _transacted = _activation.isDeliveryTransacted() || _useLocalTx ; - if (_activation.isDeliveryTransacted() && !_activation.getActivationSpec().isUseLocalTx()) + if (isXA()) { final XAResource xaResource = ((XASession)_session).getXAResource() ; - _endpoint = endpointFactory.createEndpoint(xaResource); + _endpoint = _endpointFactory.createEndpoint(xaResource); } else { - _endpoint = endpointFactory.createEndpoint(null); + _endpoint = _endpointFactory.createEndpoint(null); } _consumer.setMessageListener(this); + _connection.start(); + _activated.set(true); } /** @@ -126,11 +148,13 @@ public class QpidMessageHandler implements MessageListener */ public void teardown() { - if (_log.isTraceEnabled()) - { - _log.trace("teardown()"); - } + if (_log.isTraceEnabled()) + { + _log.trace("teardown()"); + } + super.teardown(); + try { if (_endpoint != null) @@ -156,27 +180,28 @@ public class QpidMessageHandler implements MessageListener try { - if (_activation.getActivationSpec().getTransactionTimeout() > 0 && _tm != null) + if (_spec.getTransactionTimeout() > 0 && _tm != null) { - _tm.setTransactionTimeout(_activation.getActivationSpec().getTransactionTimeout()); + _tm.setTransactionTimeout(_spec.getTransactionTimeout()); } _endpoint.beforeDelivery(QpidActivation.ONMESSAGE); beforeDelivery = true; - if(_transacted) + if(isXA()) { message.acknowledge(); } ((MessageListener)_endpoint).onMessage(message); - if (_transacted && (_tm.getTransaction() != null)) + if (isXA() && (_tm.getTransaction() != null)) { final int status = _tm.getStatus() ; final boolean rollback = status == Status.STATUS_MARKED_ROLLBACK || status == Status.STATUS_ROLLING_BACK || status == Status.STATUS_ROLLEDBACK; + if (rollback) { _session.recover() ; @@ -196,7 +221,7 @@ public class QpidMessageHandler implements MessageListener _log.warn("Unable to call after delivery", e); return; } - if (_useLocalTx) + if (!isXA() && _spec.isUseLocalTx()) { _session.commit(); } @@ -216,7 +241,7 @@ public class QpidMessageHandler implements MessageListener _log.warn("Unable to call after delivery", e); } } - if (_useLocalTx || !_activation.isDeliveryTransacted()) + if (!isXA() && _spec.isUseLocalTx()) { try { @@ -241,5 +266,17 @@ public class QpidMessageHandler implements MessageListener } } + + public void start() throws Exception + { + _deliveryActive.set(true); + setup(); + } + + public void stop() + { + _deliveryActive.set(false); + teardown(); + } } diff --git a/java/jca/src/main/java/org/apache/qpid/ra/tm/GlassfishTransactionManagerLocator.java b/java/jca/src/main/java/org/apache/qpid/ra/tm/GlassfishTransactionManagerLocator.java new file mode 100644 index 0000000000..cff53d2710 --- /dev/null +++ b/java/jca/src/main/java/org/apache/qpid/ra/tm/GlassfishTransactionManagerLocator.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.qpid.ra.tm; + + +import javax.naming.InitialContext; +import javax.transaction.TransactionManager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GlassfishTransactionManagerLocator +{ + private static final Logger _log = LoggerFactory.getLogger(GlassfishTransactionManagerLocator.class); + + private static final String TM_JNDI_NAME = "java:appserver/TransactionManager"; + + public TransactionManager getTm() throws Exception + { + InitialContext ctx = null; + TransactionManager tm = null; + + try + { + ctx = new InitialContext(); + tm = (TransactionManager)ctx.lookup(TM_JNDI_NAME); + } + catch(Exception e) + { + _log.error("Error attempting to location TM " + e.getMessage()); + } + finally + { + try + { + if(ctx != null) + { + ctx.close(); + } + } + catch(Exception ignore){} + } + + return tm; + } +} diff --git a/java/jca/src/main/java/org/apache/qpid/ra/tm/JBoss7TransactionManagerLocator.java b/java/jca/src/main/java/org/apache/qpid/ra/tm/JBoss7TransactionManagerLocator.java index 266c56bd63..6103433cbf 100644 --- a/java/jca/src/main/java/org/apache/qpid/ra/tm/JBoss7TransactionManagerLocator.java +++ b/java/jca/src/main/java/org/apache/qpid/ra/tm/JBoss7TransactionManagerLocator.java @@ -1,3 +1,23 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ package org.apache.qpid.ra.tm; import javax.naming.InitialContext; diff --git a/java/jca/src/main/java/org/apache/qpid/ra/tm/WLSTransactionManagerLocator.java b/java/jca/src/main/java/org/apache/qpid/ra/tm/WLSTransactionManagerLocator.java new file mode 100644 index 0000000000..29e673d28e --- /dev/null +++ b/java/jca/src/main/java/org/apache/qpid/ra/tm/WLSTransactionManagerLocator.java @@ -0,0 +1,64 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.qpid.ra.tm; + + +import javax.naming.InitialContext; +import javax.transaction.TransactionManager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class WLSTransactionManagerLocator +{ + private static final Logger _log = LoggerFactory.getLogger(WLSTransactionManagerLocator.class); + + private static final String TM_JNDI_NAME = "javax.transaction.TransactionManager"; + + public TransactionManager getTm() throws Exception + { + InitialContext ctx = null; + TransactionManager tm = null; + + try + { + ctx = new InitialContext(); + tm = (TransactionManager)ctx.lookup(TM_JNDI_NAME); + } + catch(Exception e) + { + _log.error("Unable to locate javax.transaction.TransactionManager " + e.getMessage()); + } + finally + { + try + { + if(ctx != null) + { + ctx.close(); + } + } + catch(Exception ignore){} + } + + return tm; + } +} + diff --git a/java/jca/src/main/resources/META-INF/ra.xml b/java/jca/src/main/resources/META-INF/ra.xml index 2c8344c8f0..a9374f52d7 100755 --- a/java/jca/src/main/resources/META-INF/ra.xml +++ b/java/jca/src/main/resources/META-INF/ra.xml @@ -69,7 +69,7 @@ </config-property> <config-property> - <description>Interval between setup attempts</description> + <description>Interval between setup attempts in milliseconds</description> <config-property-name>SetupInterval</config-property-name> <config-property-type>java.lang.Long</config-property-type> <config-property-value>5000</config-property-value> @@ -104,10 +104,17 @@ </config-property> <config-property> - <description>connection URL</description> + <description>Connection URL</description> <config-property-name>ConnectionURL</config-property-name> <config-property-type>java.lang.String</config-property-type> - <config-property-value>amqp://guest:guest@/test?brokerlist='tcp://localhost:5672'</config-property-value> + <config-property-value>amqp://anonymous:passwd@client/test?brokerlist='tcp://localhost?sasl_mechs='PLAIN''</config-property-value> + </config-property> + + <config-property> + <description>Use a JMS Connection per MessageHandler</description> + <config-property-name>UseConnectionPerHandler</config-property-name> + <config-property-type>java.lang.Boolean</config-property-type> + <config-property-value>true</config-property-value> </config-property> <outbound-resourceadapter> @@ -116,14 +123,14 @@ <config-property> <description>Default session type</description> - <config-property-name>sessionDefaultType</config-property-name> + <config-property-name>SessionDefaultType</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value>javax.jms.Queue</config-property-value> </config-property> <config-property> <description>Specify lock timeout in seconds</description> - <config-property-name>useTryLock</config-property-name> + <config-property-name>UseTryLock</config-property-name> <config-property-type>java.lang.Integer</config-property-type> <config-property-value>0</config-property-value> </config-property> @@ -137,7 +144,7 @@ <config-property> <description>Client ID for the connection</description> - <config-property-name>ClientID</config-property-name> + <config-property-name>ClientId</config-property-name> <config-property-type>java.lang.String</config-property-type> <config-property-value>client_id</config-property-value> </config-property> @@ -195,12 +202,11 @@ </messagelistener> </messageadapter> </inbound-resourceadapter> - <adminobject> <adminobject-interface>org.apache.qpid.ra.admin.QpidQueue</adminobject-interface> <adminobject-class> org.apache.qpid.ra.admin.QpidQueueImpl</adminobject-class> <config-property> - <config-property-name>destinationAddress </config-property-name> + <config-property-name>DestinationAddress </config-property-name> <config-property-type>java.lang.String </config-property-type> </config-property> </adminobject> @@ -208,30 +214,16 @@ <adminobject-interface>org.apache.qpid.ra.admin.QpidTopic</adminobject-interface> <adminobject-class> org.apache.qpid.ra.admin.QpidTopicImpl</adminobject-class> <config-property> - <config-property-name>destinationAddress </config-property-name> + <config-property-name>DestinationAddress </config-property-name> <config-property-type>java.lang.String </config-property-type> </config-property> </adminobject> - <!-- - <adminobject> - <adminobject-interface>javax.jms.Destination</adminobject-interface> - <adminobject-class> org.apache.qpid.ra.admin.QpidDestinationProxy</adminobject-class> - <config-property> - <config-property-name>destinationAddress </config-property-name> - <config-property-type>java.lang.String </config-property-type> - </config-property> - <config-property> - <config-property-name>destinationType</config-property-name> - <config-property-type>java.lang.String </config-property-type> - </config-property> - </adminobject> - --> <adminobject> <adminobject-interface>javax.jms.ConnectionFactory</adminobject-interface> <adminobject-class> org.apache.qpid.ra.admin.QpidConnectionFactoryProxy</adminobject-class> <config-property> - <config-property-name>connectionURL</config-property-name> - <config-property-type>java.lang.String </config-property-type> + <config-property-name>ConnectionURL</config-property-name> + <config-property-type>java.lang.String</config-property-type> </config-property> </adminobject> </resourceadapter> diff --git a/java/jca/src/test/java/org/apache/qpid/ra/QpidActivationSpecTest.java b/java/jca/src/test/java/org/apache/qpid/ra/QpidActivationSpecTest.java new file mode 100644 index 0000000000..e811427223 --- /dev/null +++ b/java/jca/src/test/java/org/apache/qpid/ra/QpidActivationSpecTest.java @@ -0,0 +1,45 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.ra; + +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; + +import javax.resource.spi.ResourceAdapterInternalException; + +import org.apache.qpid.ra.inflow.QpidActivationSpec; + +import junit.framework.TestCase; + +public class QpidActivationSpecTest extends TestCase +{ + + public void testActivationSpecBasicSerialization() throws Exception + { + QpidActivationSpec spec = new QpidActivationSpec(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(out); + oos.writeObject(spec); + oos.close(); + assertTrue(out.toByteArray().length > 0); + } + +} diff --git a/java/jca/src/test/java/org/apache/qpid/ra/QpidResourceAdapterTest.java b/java/jca/src/test/java/org/apache/qpid/ra/QpidResourceAdapterTest.java new file mode 100644 index 0000000000..a6788a72c5 --- /dev/null +++ b/java/jca/src/test/java/org/apache/qpid/ra/QpidResourceAdapterTest.java @@ -0,0 +1,78 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.ra; + +import javax.resource.spi.ResourceAdapterInternalException; + +import java.io.ByteArrayOutputStream; +import java.io.ObjectOutputStream; + +import junit.framework.TestCase; + + +public class QpidResourceAdapterTest extends TestCase +{ + public void testGetXAResources() throws Exception + { + QpidResourceAdapter ra = new QpidResourceAdapter(); + assertNull(ra.getXAResources(null)); + } + + public void testTransactionManagerLocatorException() throws Exception + { + + QpidResourceAdapter ra = new QpidResourceAdapter(); + assertNull(ra.getTransactionManagerLocatorClass()); + assertNull(ra.getTransactionManagerLocatorMethod()); + + try + { + ra.start(null); + } + catch(ResourceAdapterInternalException e) + { + + } + + ra.setTransactionManagerLocatorClass("DummyLocator"); + + try + { + ra.start(null); + } + catch(ResourceAdapterInternalException e) + { + + } + + } + + public void testResourceAdapterBasicSerialization() throws Exception + { + + QpidResourceAdapter ra = new QpidResourceAdapter(); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(out); + oos.writeObject(ra); + oos.close(); + assertTrue(out.toByteArray().length > 0); + } +} |
