diff options
author | Andrew Stitcher <astitcher@apache.org> | 2011-12-18 05:09:07 +0000 |
---|---|---|
committer | Andrew Stitcher <astitcher@apache.org> | 2011-12-18 05:09:07 +0000 |
commit | fb08688252d1043b202e1b88a9cd5b37da67794c (patch) | |
tree | 918cb48793f3c686e52f8ccf714b306a65f53852 /java/jca/example | |
parent | d9ff8e43999e4c59d4092064a6e2c80773534864 (diff) | |
download | qpid-python-fb08688252d1043b202e1b88a9cd5b37da67794c.tar.gz |
QPID-3044: Implement JCA Adapter for Java JMS client
- Large contributions from Weston Price & Kevin Conner
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1220336 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/jca/example')
31 files changed, 2879 insertions, 0 deletions
diff --git a/java/jca/example/.gitignore b/java/jca/example/.gitignore new file mode 100644 index 0000000000..597acff14b --- /dev/null +++ b/java/jca/example/.gitignore @@ -0,0 +1,2 @@ +build/* +lib/* diff --git a/java/jca/example/README.txt b/java/jca/example/README.txt new file mode 100644 index 0000000000..d94bbfa7e5 --- /dev/null +++ b/java/jca/example/README.txt @@ -0,0 +1,277 @@ +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 new file mode 100644 index 0000000000..79cf5adc74 --- /dev/null +++ b/java/jca/example/build-geronimo-properties.xml @@ -0,0 +1,169 @@ +<!-- + - + - 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-geronimo-properties" basedir="." default=""> + + <property name="geronimo.jndi.scheme" value="name"/> + <property name="qpid.xacf.jndi.name" value="jca:/qpid.jca/QpidJCAAdapter/JCAManagedConnectionFactory/QpidJMSXA"/> + <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.ejb.jndi.name" value="name="QpidTestEJB""/> + <property name="qpid.ejb.name" value="QpidTestBeanRemote"/> + + <property name="jndi.context" value="org.openejb.client.RemoteInitialContextFactory"/> + <property name="server.host" value="ejbd://localhost:4201"/> + <property name="geronimo.home" location="${env.GERONIMO_HOME}"/> + <property name="geronimo.user" value="system"/> + <property name="geronimo.password" value="manager"/> + + <property name="geronimo.rar.group.id" value="qpid.jca"/> + <property name="geronimo.rar.artifact.id" value="QpidJCAAdapter"/> + <property name="geronimo.rar.version" value="1.0"/> + <property name="geronimo.rar.type" value="rar"/> + <property name="geronimo.rar.id" value="${geronimo.rar.group.id}/${geronimo.rar.artifact.id}/${geronimo.rar.version}/${geronimo.rar.type}"/> + + <property name="geronimo.ejb.group.id" value="qpid.jca.example"/> + <property name="geronimo.ejb.artifact.id" value="QpidJCAEJBExample"/> + <property name="geronimo.ejb.version" value="1.0"/> + <property name="geronimo.ejb.type" value="car"/> + <property name="geronimo.ejb.id" value="${geronimo.ejb.group.id}/${geronimo.ejb.artifact.id}/${geronimo.ejb.version}/${geronimo.ejb.type}"/> + + <property name="geronimo.war.group.id" value="qpid.jca.example"/> + <property name="geronimo.war.artifact.id" value="QpidJCAWebExample"/> + <property name="geronimo.war.version" value="1.0"/> + <property name="geronimo.war.type" value="war"/> + <property name="geronimo.war.id" value="${geronimo.war.group.id}/${geronimo.war.artifact.id}/${geronimo.war.version}/${geronimo.war.type}"/> + + <property name="geronimo.ear.group.id" value="qpid.jca.example"/> + <property name="geronimo.ear.artifact.id" value="QpidJCAEARExample"/> + <property name="geronimo.ear.version" value="1.0"/> + <property name="geronimo.ear.type" value="ear"/> + <property name="geronimo.ear.id" value="${geronimo.ear.group.id}/${geronimo.ear.artifact.id}/${geronimo.ear.version}/${geronimo.ear.type}"/> + + <property name="geronimo.rar.plan" value="${gen.dir}/geronimo-ra.xml"/> + <property name="geronimo.ear.plan" value="${gen.dir}/geronimo-application.xml"/> + + <path id="compile.classpath"> + <fileset dir="${geronimo.home}/repository/org/apache/geronimo/specs"> + <include name="geronimo-jms_1.1_spec/1.1.1/geronimo-jms_1.1_spec-1.1.1.jar"/> + <include name="geronimo-servlet_2.5_spec/1.2/geronimo-servlet_2.5_spec-1.2.jar"/> + <include name="geronimo-ejb_3.0_spec/1.0.1/geronimo-ejb_3.0_spec-1.0.1.jar"/> + <include name="geronimo-jta_1.1_spec/1.1.1/geronimo-jta_1.1_spec-1.1.1.jar"/> + </fileset> + <fileset dir="${geronimo.home}/lib/"> + <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="${geronimo.home}/repository/org/apache/geronimo/specs"> + <include name="geronimo-j2ee-connector_1.5_spec/2.0.0/geronimo-j2ee-connector_1.5_spec-2.0.0.jar"/> + <include name="geronimo-jms_1.1_spec/1.1.1/geronimo-jms_1.1_spec-1.1.1.jar"/> + <include name="geronimo-servlet_2.5_spec/1.2/geronimo-servlet_2.5_spec-1.2.jar"/> + <include name="geronimo-ejb_3.0_spec/1.0.1/geronimo-ejb_3.0_spec-1.0.1.jar"/> + <include name="geronimo-jta_1.1_spec/1.1.1/geronimo-jta_1.1_spec-1.1.1.jar"/> + </fileset> + <fileset dir="${geronimo.home}/lib/"> + <include name="slf4j-api-*.jar"/> + <include name="slf4j-log4j*-*.jar"/> + <include name="log4j-*.jar"/> + </fileset> + <fileset dir="${geronimo.home}/repository/org/apache/openejb/openejb-client/3.1.4/"/> + </path> + + <filterset id="extra.filterset"> + <filter token="geronimo.ejb.group.id" value="${geronimo.ejb.group.id}"/> + <filter token="geronimo.ejb.artifact.id" value="${geronimo.ejb.artifact.id}"/> + <filter token="geronimo.ejb.version" value="${geronimo.ejb.version}"/> + <filter token="geronimo.ejb.type" value="${geronimo.ejb.type}"/> + <filter token="geronimo.war.group.id" value="${geronimo.war.group.id}"/> + <filter token="geronimo.war.artifact.id" value="${geronimo.war.artifact.id}"/> + <filter token="geronimo.war.version" value="${geronimo.war.version}"/> + <filter token="geronimo.war.type" value="${geronimo.war.type}"/> + <filter token="geronimo.ear.group.id" value="${geronimo.ear.group.id}"/> + <filter token="geronimo.ear.artifact.id" value="${geronimo.ear.artifact.id}"/> + <filter token="geronimo.ear.version" value="${geronimo.ear.version}"/> + <filter token="geronimo.ear.type" value="${geronimo.ear.type}"/> + </filterset> + + <macrodef name="geronimo"> + <attribute name="user" default="${geronimo.user}"/> + <attribute name="password" default="${geronimo.password}"/> + <attribute name="action" default="list-modules"/> + <attribute name="module"/> + <attribute name="plan" default=""/> + <sequential> + <exec executable="${geronimo.home}/bin/deploy.sh"> + <arg line="-u @{user} -p @{password} @{action} @{module} @{plan}"/> + </exec> + </sequential> + </macrodef> + + <!-- Deployment is target specific so is included here --> + <target name="deploy-rar" depends="generate" description="Deploy the RAR file."> + <geronimo action="deploy" module="${qpid.jca.dir}/${rar.name}" plan="${geronimo.rar.plan}"/> + </target> + + <target name="undeploy-rar" description="Undeploys the RAR deployment."> + <geronimo action="undeploy" module="${geronimo.rar.id}"/> + </target> + + <target name="start-rar" description="Starts the RAR deployment in the Geronimo environment."> + <geronimo action="start" module="${geronimo.rar.id}"/> + </target> + + <target name="stop-rar" description="Stops the RAR deployment in the Geronimo environment."> + <geronimo action="stop" module="${geronimo.rar.id}"/> + </target> + + <target name="restart-rar" description="Restarts the RAR deployment in the Geronimo environment."> + <geronimo action="restart" module="${geronimo.rar.id}"/> + </target> + + <target name="deploy-ear" depends="package-ear" description="Deploys the EAR archive."> + <geronimo action="deploy" module="${build.dir}/${ear.name}" plan="${geronimo.ear.plan}"/> + </target> + + <target name="undeploy-ear" description="Undeployes the EAR archive."> + <geronimo action="undeploy" module="${geronimo.ear.id}"/> + </target> + + <target name="start-ear" description="Starts the EAR deployment in the Geronimo environment."> + <geronimo action="start" module="${geronimo.ear.id}"/> + </target> + + <target name="stop-ear" description="Stops the EAR deployment in the Geronimo environment."> + <geronimo action="stop" module="${geronimo.ear.id}"/> + </target> + + <target name="restart-ear" description="Restarts the EAR deployment in the Geronimo environment."> + <geronimo action="restart" module="${geronimo.ear.id}"/> + </target> + +</project> diff --git a/java/jca/example/build-jboss-properties.xml b/java/jca/example/build-jboss-properties.xml new file mode 100644 index 0000000000..3554488d2d --- /dev/null +++ b/java/jca/example/build-jboss-properties.xml @@ -0,0 +1,115 @@ +<!-- + - + - 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-jboss-properties" basedir="." default=""> + + <property name="jboss.jndi.scheme" value="mappedName"/> + <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.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="jndi.context" value="org.jnp.interfaces.NamingContextFactory"/> + <property name="server.host" value="jnp://localhost:1099"/> + + <property name="jboss.home" location="${env.JBOSS_HOME}"/> + <property name="jboss.server" value="default"/> + <property name="jboss.deploy" location="${jboss.home}/server/${jboss.server}/deploy"/> + <property name="jboss.client" location="${jboss.home}/client"/> + + <path id="compile.classpath"> + <fileset dir="${jboss.client}"> + <!-- JBoss 5--> + <include name="jboss-javaee.jar"/> + + <!-- JBoss 6 --> + <include name="jboss-servlet-api_3.0_spec.jar"/> + <include name="jboss-jms-api_1.1_spec.jar"/> + <include name="jboss-ejb-api_3.1_spec.jar"/> + <include name="jboss-transaction-api_1.1_spec.jar"/> + + <!-- Common to JBoss 5/6 --> + <include name="slf4j-api.jar"/> + </fileset> + + <!-- JBoss 5 --> + <fileset dir="${jboss.home}/common/lib"> + <include name="servlet-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="${jboss.client}"> + <!-- Shortcut to get it working!--> + <include name="jbossall-client.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-ds" depends="generate" description="Deploys the ds.xml file to the JBoss environment."> + <copy todir="${jboss.deploy}" overwrite="true"> + <fileset dir="${gen.dir}"> + <include name="qpid-jca-ds.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-properties.xml b/java/jca/example/build-properties.xml new file mode 100644 index 0000000000..5ac1d50ce9 --- /dev/null +++ b/java/jca/example/build-properties.xml @@ -0,0 +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. + - + --> +<project name="qpid-jca-example-build-properties" basedir="." default=""> + <property name="qpid.ver" value="0.15"/> +</project> diff --git a/java/jca/example/build-properties.xml.temp b/java/jca/example/build-properties.xml.temp new file mode 100644 index 0000000000..9eae869c27 --- /dev/null +++ b/java/jca/example/build-properties.xml.temp @@ -0,0 +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. + - + --> +<project name="qpid-jca-example-build-properties" basedir="." default=""> + <property name="qpid.ver" value="@project.version@"/> +</project> diff --git a/java/jca/example/build.xml b/java/jca/example/build.xml new file mode 100644 index 0000000000..9d0cfc887e --- /dev/null +++ b/java/jca/example/build.xml @@ -0,0 +1,204 @@ +<!-- + - + - 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" default="help" basedir=""> + + <!-- Valid target platforms are currently geronimo & jboss --> + <property name="target.platform" value="geronimo"/> + + <!-- Change to BURL for older syntax support --> + <property name="qpid.dest_syntax" value="ADDR"/> + + <!-- Broker specific properties. By default in the adapter we use localhost here you an override this with host specific info--> + <property name="broker.address" value="localhost"/> + + <!-- Properties controlling running sample standalone client --> + <property name="client.use.ejb" value="false"/> <!-- uses JNDI/JMS or JNDI/RMI --> + <property name="client.message" value="Hello Qpid World"/> + <property name="client.message.count" value="1"/> + <property name="client.use.topic" value="false"/> <!-- Use topic/queue --> + <property name="client.say.goodbye" value="false"/> + + <!-- Pull in environment vars as properties --> + <property environment="env"/> + + <!-- QPID version property --> + <import file="${basedir}/build-properties.xml"/> + + <import file="${basedir}/qpid-jca-example-properties.xml"/> + + <!-- Target specific properties/targets --> + <import file="${basedir}/build-${target.platform}-properties.xml"/> + + <macrodef name="compile"> + <attribute name="classpath"/> + <sequential> + <javac srcdir="${gen.dir}" + destdir="${build.classes.dir}" + classpathref="@{classpath}" + debug="true" optimize="false"/> + </sequential> + </macrodef> + + <echo message="Using Qpid version ${qpid.ver}"/> + <echo message="Building for platform ${target.platform}"/> + <echo message="Broker url is currently set to ${broker.url}"/> + <echo message="Qpid Destination Syntax is ${qpid.dest_syntax}"/> + + <target name="init"> + <mkdir dir="${build.classes.dir}"/> + <mkdir dir="${gen.dir}"/> + <mkdir dir="${log.dir}"/> + </target> + + <target name="generate" depends="init"> + <copy todir="${gen.dir}" overwrite="true"> + <fileset dir="${conf.dir}"/> + <filterset> + <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}"/> + <filter token="qpid.goodbye.topic.dest.address" value="${qpid.goodbye.topic.dest.address}"/> + <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}"/> + + </filterset> + <filterset refid="extra.filterset"/> + </copy> + <copy todir="${gen.dir}"> + <fileset dir="${src.dir}"/> + <filterset> + <filter token="rar.name" value="${rar.name}"/> + <filter token="broker.url" value="${broker.url}"/> + <filter token="jndi.scheme" value="${jndi.scheme}"/> + <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.ejb.jndi.name" value="${qpid.ejb.jndi.name}"/> + </filterset> + </copy> + </target> + + <target name="compile" depends="generate" description="Compiles the source files for the Qpid JCA example"> + <compile classpath="compile.classpath"/> + </target> + + <target name="package-war" depends="compile" description="Packages the WAR file for deployment."> + <war destfile="${build.dir}/${war.name}" webxml="${gen.dir}/web.xml"> + <classes dir="${build.classes.dir}"> + <include name="org/apache/qpid/jca/example/web/**"/> + </classes> + <webinf dir="${gen.dir}"> + <include name="jboss-web.xml"/> + </webinf> + </war> + </target> + + <target name="package-ejb" depends="compile" description="Packages the EJB archive for deployment."> + <jar destfile="${build.dir}/${ejb.name}" basedir="${build.classes.dir}"> + <include name="org/apache/qpid/jca/example/ejb/**/*.class"/> + <metainf dir="${gen.dir}"> + <include name="jboss.xml"/> + <include name="ejb-jar.xml"/> + </metainf> + </jar> + </target> + + <target name="package-ear" depends="generate, package-war, package-ejb" description="Packages the EAR archive for deployment."> + <jar destfile="${build.dir}/${ear.name}" basedir="${build.dir}"> + <include name="*.war"/> + <include name="*.jar"/> + <metainf dir="${gen.dir}"> + <include name="application.xml"/> + </metainf> + </jar> + </target> + + <target name="run-client" depends="compile" description="Runs the RMI client."> + <java classname="org.apache.qpid.jca.example.client.QpidTestClient"> + <classpath> + <pathelement path="${build.classes.dir}"/> + <path refid="run.classpath"/> + </classpath> + <sysproperty key="java.naming.factory.initial" value="${jndi.context}"/> + <sysproperty key="java.naming.provider.url" value="${server.host}"/> + <sysproperty key="qpid.ejb.name" value="${qpid.ejb.name}"/> + <sysproperty key="qpid.cf.name" value="${qpid.cf.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}"/> + <sysproperty key="message.count" value="${client.message.count}"/> + <sysproperty key="use.topic" value="${client.use.topic}"/> + <sysproperty key="use.ejb" value="${client.use.ejb}"/> + <sysproperty key="say.goodbye" value="${client.say.goodbye}"/> + </java> + </target> + + <target name="run-reqresp" depends="compile"> + <java classname="org.apache.qpid.jca.example.client.QpidRequestResponseClient"> + <classpath> + <pathelement path="${build.classes.dir}"/> + <path refid="run.classpath"/> + </classpath> + <sysproperty key="java.naming.factory.initial" value="${jndi.context}"/> + <sysproperty key="java.naming.provider.url" value="${server.host}"/> + <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="log4j.configuration" value="file://${conf.dir}/log4j.properties"/> + <sysproperty key="qpid.dest_syntax" value="${qpid.dest_syntax}"/> + </java> + </target> + + <target name="clean" description="Deletes the build directory and all related files."> + <delete dir="${build.dir}"/> + </target> + + <target name="help"> + <echo> + + ant compile + This will compile all the source code for the Qpid JCA example project to the ${build.classes.dir} directory. + + ant deploy-rar deploy-ear + Deploys a particular component which could be rar, ear (or ds for JBoss) + + ant undeploy-ear undeploy-rar + Undeploys a particular component which could be rar, ear (or ds for JBoss) + + ant run-client run-reqresp + Runs the RMI/thin client or the request-response client example + </echo> + </target> + +</project> diff --git a/java/jca/example/conf/application.xml b/java/jca/example/conf/application.xml new file mode 100644 index 0000000000..d181bcda67 --- /dev/null +++ b/java/jca/example/conf/application.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + - + - 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. + - + --> +<application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="5" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_5.xsd"> + + <module> + <ejb>@ejb.name@</ejb> + </module> + + <module> + <web> + <web-uri>@war.name@</web-uri> + <context-root>/qpid-jca-web</context-root> + </web> + </module> + +</application> + diff --git a/java/jca/example/conf/ejb-jar.xml b/java/jca/example/conf/ejb-jar.xml new file mode 100644 index 0000000000..2f513bd3f8 --- /dev/null +++ b/java/jca/example/conf/ejb-jar.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- + - + - 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. + - + --> +<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" version="3.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee + http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"> + + <enterprise-beans> + <message-driven> + <ejb-name>QpidHelloListenerBean</ejb-name> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <res-type>javax.jms.ConnectionFactory</res-type> + <res-auth>Container</res-auth> + <res-sharing-scope>Shareable</res-sharing-scope> + </resource-ref> + </message-driven> + <message-driven> + <ejb-name>QpidHelloSubscriberBean</ejb-name> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <res-type>javax.jms.ConnectionFactory</res-type> + <res-auth>Container</res-auth> + <res-sharing-scope>Shareable</res-sharing-scope> + </resource-ref> + </message-driven> + <message-driven> + <ejb-name>QpidJMSResponderBean</ejb-name> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <res-type>javax.jms.ConnectionFactory</res-type> + <res-auth>Container</res-auth> + <res-sharing-scope>Shareable</res-sharing-scope> + </resource-ref> + </message-driven> + <session> + <ejb-name>QpidTestBean</ejb-name> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <res-type>javax.jms.ConnectionFactory</res-type> + <res-auth>Container</res-auth> + <res-sharing-scope>Shareable</res-sharing-scope> + </resource-ref> + </session> + </enterprise-beans> + + +</ejb-jar> diff --git a/java/jca/example/conf/geronimo-application.xml b/java/jca/example/conf/geronimo-application.xml new file mode 100644 index 0000000000..832496e76f --- /dev/null +++ b/java/jca/example/conf/geronimo-application.xml @@ -0,0 +1,151 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + - + - 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. + - + --> +<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" + application-name="QpidJCAExampleApplication"> + + <sys:environment> + <sys:moduleId> + <sys:groupId>@geronimo.ear.group.id@</sys:groupId> + <sys:artifactId>@geronimo.ear.artifact.id@</sys:artifactId> + <sys:version>@geronimo.ear.version@</sys:version> + <sys:type>@geronimo.ear.type@</sys:type> + </sys:moduleId> + </sys:environment> + + <!-- Plan for embedded WAR --> + <module> + <web>qpid-jcaex-web.war</web> + <web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-2.0.1"> + + <sys:environment> + <sys:moduleId> + <sys:groupId>@geronimo.war.group.id@</sys:groupId> + <sys:artifactId>@geronimo.war.artifact.id@</sys:artifactId> + <sys:version>@geronimo.war.version@</sys:version> + <sys:type>@geronimo.war.type@</sys:type> + </sys:moduleId> + + <sys:dependencies> + <sys:dependency> + <sys:groupId>qpid.jca</sys:groupId> + <sys:artifactId>QpidJCAAdapter</sys:artifactId> + <sys:version>1.0</sys:version> + <sys:type>rar</sys:type> + </sys:dependency> + </sys:dependencies> + </sys:environment> + + <context-root>/qpid-jca-web</context-root> + + <naming:ejb-local-ref> + <naming:ref-name>QpidTestBean</naming:ref-name> + <naming:ejb-link>QpidTestBean</naming:ejb-link> + </naming:ejb-local-ref> + + <naming:resource-ref> + <naming:ref-name>QpidJMSXA</naming:ref-name> + <naming:resource-link>QpidJMSXA</naming:resource-link> + </naming:resource-ref> + </web-app> + </module> + + <!-- Plan for embedded EJBs --> + <module> + <ejb>qpid-jcaex-ejb.jar</ejb> + <openejb-jar xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.1"> + + <sys:environment> + <sys:moduleId> + <sys:groupId>@geronimo.ejb.group.id@</sys:groupId> + <sys:artifactId>@geronimo.ejb.artifact.id@</sys:artifactId> + <sys:version>@geronimo.ejb.version@</sys:version> + <sys:type>@geronimo.ejb.type@</sys:type> + </sys:moduleId> + + <sys:dependencies> + <sys:dependency> + <sys:groupId>qpid.jca</sys:groupId> + <sys:artifactId>QpidJCAAdapter</sys:artifactId> + <sys:version>1.0</sys:version> + <sys:type>rar</sys:type> + </sys:dependency> + </sys:dependencies> + <sys:hidden-classes/> + <sys:non-overridable-classes/> + </sys:environment> + + <enterprise-beans> + <message-driven> + <ejb-name>QpidHelloListenerBean</ejb-name> + <resource-adapter> + <resource-link>QpidResourceAdapter</resource-link> + </resource-adapter> + <naming:resource-ref> + <naming:ref-name>QpidJMSXA</naming:ref-name> + <naming:resource-link>QpidJMSXA</naming:resource-link> + </naming:resource-ref> + </message-driven> + <message-driven> + <ejb-name>QpidGoodByeListenerBean</ejb-name> + <resource-adapter> + <resource-link>QpidResourceAdapter</resource-link> + </resource-adapter> + </message-driven> + <message-driven> + <ejb-name>QpidHelloSubscriberBean</ejb-name> + <resource-adapter> + <resource-link>QpidResourceAdapter</resource-link> + </resource-adapter> + <naming:resource-ref> + <naming:ref-name>QpidJMSXA</naming:ref-name> + <naming:resource-link>QpidJMSXA</naming:resource-link> + </naming:resource-ref> + </message-driven> + <message-driven> + <ejb-name>QpidGoodByeSubscriberBean</ejb-name> + <resource-adapter> + <resource-link>QpidResourceAdapter</resource-link> + </resource-adapter> + </message-driven> + <message-driven> + <ejb-name>QpidJMSResponderBean</ejb-name> + <resource-adapter> + <resource-link>QpidResourceAdapter</resource-link> + </resource-adapter> + <naming:resource-ref> + <naming:ref-name>QpidJMSXA</naming:ref-name> + <naming:resource-link>QpidJMSXA</naming:resource-link> + </naming:resource-ref> + </message-driven> + <session> + <ejb-name>QpidTestBean</ejb-name> + <naming:resource-ref> + <naming:ref-name>QpidJMSXA</naming:ref-name> + <naming:resource-link>QpidJMSXA</naming:resource-link> + </naming:resource-ref> + </session> + </enterprise-beans> + </openejb-jar> + </module> +</application> diff --git a/java/jca/example/conf/geronimo-ra.xml b/java/jca/example/conf/geronimo-ra.xml new file mode 100644 index 0000000000..2943ac0a58 --- /dev/null +++ b/java/jca/example/conf/geronimo-ra.xml @@ -0,0 +1,138 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + - + - 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. + - + --> +<connector xmlns="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2"> + <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.2"> + <dep:moduleId> + <dep:groupId>qpid.jca</dep:groupId> + <dep:artifactId>QpidJCAAdapter</dep:artifactId> + <dep:version>1.0</dep:version> + <dep:type>rar</dep:type> + </dep:moduleId> + </dep:environment> + <resourceadapter> + <resourceadapter-instance> + <resourceadapter-name>QpidResourceAdapter</resourceadapter-name> + <config-property-setting name="ClientId">client_id</config-property-setting> + <config-property-setting name="TransactionManagerLocatorClass">org.apache.qpid.ra.tm.GeronimoTransactionManagerLocator</config-property-setting> + <config-property-setting name="TransactionManagerLocatorMethod">getTransactionManager</config-property-setting> + <!-- Note, currently there is a bug with end/suspend and Geronimo. For now use local transactions--> + <config-property-setting name="UseLocalTx">true</config-property-setting> + <workmanager> + <gbean-link>DefaultWorkManager</gbean-link> + </workmanager> + </resourceadapter-instance> + <outbound-resourceadapter> + <connection-definition> + <connectionfactory-interface>org.apache.qpid.ra.QpidRAConnectionFactory</connectionfactory-interface> + <connectiondefinition-instance> + <name>QpidJMSXA</name> + <implemented-interface>javax.jms.QueueConnectionFactory</implemented-interface> + <implemented-interface>javax.jms.TopicConnectionFactory</implemented-interface> + <config-property-setting name="ConnectionURL">@broker.url@</config-property-setting> + <connectionmanager> + <!-- Note, currently there is a bug with end/suspend and Geronimo. For now use no transactions outbound --> + <no-transaction/> + <single-pool> + <max-size>20</max-size> + <min-size>0</min-size> + <match-one/> + </single-pool> + </connectionmanager> + </connectiondefinition-instance> + </connection-definition> + </outbound-resourceadapter> + <!-- Note, do not remove this admin object. There appears to be a bug in Geronimo's deployer that does not correctly create JNDI references + if an extra admin object is not present --> + <adminobject> + <adminobject-interface>javax.jms.Destination</adminobject-interface> + <adminobject-class>org.apache.qpid.ra.admin.QpidDestinationProxy</adminobject-class> + <adminobject-instance> + <message-destination-name>Dummy</message-destination-name> + <config-property-setting name="destinationType">TOPIC</config-property-setting> + <config-property-setting name="destinationAddress">amq.topic</config-property-setting> + </adminobject-instance> + </adminobject> + <adminobject> + <adminobject-interface>javax.jms.Destination</adminobject-interface> + <adminobject-class>org.apache.qpid.ra.admin.QpidDestinationProxy</adminobject-class> + <adminobject-instance> + <message-destination-name>HelloTopic</message-destination-name> + <config-property-setting name="destinationType">TOPIC</config-property-setting> + <config-property-setting name="destinationAddress">@qpid.hello.topic.dest.address@</config-property-setting> + </adminobject-instance> + </adminobject> + <adminobject> + <adminobject-interface>javax.jms.Destination</adminobject-interface> + <adminobject-class>org.apache.qpid.ra.admin.QpidDestinationProxy</adminobject-class> + <adminobject-instance> + <message-destination-name>GoodByeTopic</message-destination-name> + <config-property-setting name="destinationType">TOPIC</config-property-setting> + <config-property-setting name="destinationAddress">@qpid.goodbye.topic.dest.address@</config-property-setting> + </adminobject-instance> + </adminobject> + <adminobject> + <adminobject-interface>javax.jms.Destination</adminobject-interface> + <adminobject-class>org.apache.qpid.ra.admin.QpidDestinationProxy</adminobject-class> + <adminobject-instance> + <message-destination-name>HelloGoodByeTopic</message-destination-name> + <config-property-setting name="destinationType">TOPIC</config-property-setting> + <config-property-setting name="destinationAddress">@qpid.hellogoodbye.topic.dest.address@</config-property-setting> + </adminobject-instance> + </adminobject> + <adminobject> + <adminobject-interface>javax.jms.Destination</adminobject-interface> + <adminobject-class>org.apache.qpid.ra.admin.QpidDestinationProxy</adminobject-class> + <adminobject-instance> + <message-destination-name>HelloQueue</message-destination-name> + <config-property-setting name="destinationType">QUEUE</config-property-setting> + <config-property-setting name="destinationAddress">@qpid.hello.queue.dest.address@</config-property-setting> + </adminobject-instance> + </adminobject> + <adminobject> + <adminobject-interface>javax.jms.Destination</adminobject-interface> + <adminobject-class>org.apache.qpid.ra.admin.QpidDestinationProxy</adminobject-class> + <adminobject-instance> + <message-destination-name>GoodByeQueue</message-destination-name> + <config-property-setting name="destinationType">QUEUE</config-property-setting> + <config-property-setting name="destinationAddress">@qpid.goodbye.queue.dest.address@</config-property-setting> + </adminobject-instance> + </adminobject> + <adminobject> + <adminobject-interface>javax.jms.Destination</adminobject-interface> + <adminobject-class>org.apache.qpid.ra.admin.QpidDestinationProxy</adminobject-class> + <adminobject-instance> + <message-destination-name>ResponderQueue</message-destination-name> + <config-property-setting name="destinationType">QUEUE</config-property-setting> + <config-property-setting name="destinationAddress">@qpid.responder.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> + </adminobject-instance> + </adminobject> + </resourceadapter> +</connector> + diff --git a/java/jca/example/conf/jboss-web.xml b/java/jca/example/conf/jboss-web.xml new file mode 100644 index 0000000000..edacf8d418 --- /dev/null +++ b/java/jca/example/conf/jboss-web.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + - + - 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. + - + --> +<jboss-web> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <res-type>javax.jms.ConnectionFactory</res-type> + <jndi-name>java:/QpidJMSXA</jndi-name> + </resource-ref> + <ejb-local-ref> + <ejb-ref-name>QpidTestBean</ejb-ref-name> + <jndi-name>qpid-jcaex/QpidTestBean/local</jndi-name> + </ejb-local-ref> + <context-root>qpid-jca-web</context-root> +</jboss-web> + diff --git a/java/jca/example/conf/jboss.xml b/java/jca/example/conf/jboss.xml new file mode 100644 index 0000000000..8b62ca73b0 --- /dev/null +++ b/java/jca/example/conf/jboss.xml @@ -0,0 +1,80 @@ +<?xml version="1.0"?> +<!-- + - + - 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. + - + --> +<jboss + xmlns="http://www.jboss.com/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee + http://www.jboss.org/j2ee/schema/jboss_5_0.xsd" + version="3.0"> + + <enterprise-beans> + <message-driven> + <ejb-name>QpidHelloListenerBean</ejb-name> + <resource-adapter-name>@rar.name@</resource-adapter-name> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <res-type>javax.sql.DataSource</res-type> + <jndi-name>java:/QpidJMSXA</jndi-name> + </resource-ref> + </message-driven> + <message-driven> + <ejb-name>QpidGoodByeListenerBean</ejb-name> + <resource-adapter-name>@rar.name@</resource-adapter-name> + </message-driven> + <message-driven> + <ejb-name>QpidHelloSubscriberBean</ejb-name> + <resource-adapter-name>@rar.name@</resource-adapter-name> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <res-type>javax.sql.DataSource</res-type> + <jndi-name>java:/QpidJMSXA</jndi-name> + </resource-ref> + </message-driven> + <message-driven> + <ejb-name>QpidGoodByeSubscriberBean</ejb-name> + <resource-adapter-name>@rar.name@</resource-adapter-name> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <res-type>javax.sql.DataSource</res-type> + <jndi-name>java:/QpidJMSXA</jndi-name> + </resource-ref> + </message-driven> + <message-driven> + <ejb-name>QpidJMSResponderBean</ejb-name> + <resource-adapter-name>@rar.name@</resource-adapter-name> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <res-type>javax.sql.DataSource</res-type> + <jndi-name>java:/QpidJMSXA</jndi-name> + </resource-ref> + </message-driven> + <session> + <ejb-name>QpidTestBean</ejb-name> + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <res-type>javax.sql.DataSource</res-type> + <jndi-name>java:/QpidJMSXA</jndi-name> + </resource-ref> + </session> + </enterprise-beans> + +</jboss> diff --git a/java/jca/example/conf/log4j.properties b/java/jca/example/conf/log4j.properties new file mode 100644 index 0000000000..f1847f4418 --- /dev/null +++ b/java/jca/example/conf/log4j.properties @@ -0,0 +1,18 @@ +log4j.rootLogger=DEBUG, CONSOLE, FILE + +#Console Appender +log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender +log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout +log4j.appender.CONSOLE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n + +#File Appender +log4j.appender.FILE=org.apache.log4j.FileAppender +log4j.appender.FILE.File=./build/log/qpid-jca-example.log +log4j.appender.FILE.layout=org.apache.log4j.PatternLayout +log4j.appender.FILE.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n + +log4j.logger.org.jboss=WARN +log4j.logger.org.jnp.interfaces=WARN +log4j.logger.org.apache.qpid=ERROR +log4j.logger.org.apache.qpid.jca.example=DEBUG + diff --git a/java/jca/example/conf/qpid-jca-ds.xml b/java/jca/example/conf/qpid-jca-ds.xml new file mode 100644 index 0000000000..9e589169e3 --- /dev/null +++ b/java/jca/example/conf/qpid-jca-ds.xml @@ -0,0 +1,123 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + - + - 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. + - + --> +<connection-factories> + + <mbean code="org.jboss.resource.deployment.AdminObject" + name="qpid.jca:name=HelloTopic"> + <attribute name="JNDIName">HelloTopic</attribute> + <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> + <attribute name="Type">javax.jms.Destination</attribute> + <attribute name="Properties"> + destinationType=TOPIC + destinationAddress=@qpid.hello.topic.dest.address@ + </attribute> + </mbean> + + <mbean code="org.jboss.resource.deployment.AdminObject" + name="qpid.jca:name=GoodByeTopic"> + <attribute name="JNDIName">GoodByeTopic</attribute> + <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> + <attribute name="Type">javax.jms.Destination</attribute> + <attribute name="Properties"> + destinationType=TOPIC + destinationAddress=@qpid.goodbye.topic.dest.address@ + </attribute> + </mbean> + + <mbean code="org.jboss.resource.deployment.AdminObject" + name="qpid.jca:name=HelloGoodByeTopic"> + <attribute name="JNDIName">HelloGoodByeTopic</attribute> + <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> + <attribute name="Type">javax.jms.Destination</attribute> + <attribute name="Properties"> + destinationType=TOPIC + destinationAddress=@qpid.hellogoodbye.topic.dest.address@ + </attribute> + </mbean> + + <mbean code="org.jboss.resource.deployment.AdminObject" + name="qpid.jca:name=HelloQueue"> + <attribute name="JNDIName">HelloQueue</attribute> + <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> + <attribute name="Type">javax.jms.Destination</attribute> + <attribute name="Properties"> + destinationType=QUEUE + destinationAddress=@qpid.hello.queue.dest.address@ + </attribute> + </mbean> + + <mbean code="org.jboss.resource.deployment.AdminObject" + name="qpid.jca:name=GoodByeQueue"> + <attribute name="JNDIName">GoodByeQueue</attribute> + <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> + <attribute name="Type">javax.jms.Destination</attribute> + <attribute name="Properties"> + destinationType=QUEUE + 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> + <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name='@rar.name@'</depends> + <attribute name="Type">javax.jms.Destination</attribute> + <attribute name="Properties"> + destinationType=QUEUE + destinationAddress=@qpid.responder.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@ + </attribute> + </mbean> + + <!-- Non XA connection factory. Can be used when running adapter against clustered Brokers --> + <tx-connection-factory> + <jndi-name>QpidJMS</jndi-name> + <rar-name>@rar.name@</rar-name> + <local-transaction/> + <config-property name="useLocalTx" type="java.lang.Boolean">true</config-property> + <config-property name="connectionURL">@broker.url@</config-property> + <config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Queue</config-property> + <connection-definition>org.apache.qpid.ra.QpidRAConnectionFactory</connection-definition> + <max-pool-size>20</max-pool-size> + </tx-connection-factory> + + <!--XA ConnectionFactory--> + <tx-connection-factory> + <jndi-name>QpidJMSXA</jndi-name> + <xa-transaction/> + <rar-name>@rar.name@</rar-name> + <config-property name="connectionURL">@broker.url@</config-property> + <config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Queue</config-property> + <connection-definition>org.apache.qpid.ra.QpidRAConnectionFactory</connection-definition> + <max-pool-size>20</max-pool-size> + </tx-connection-factory> + +</connection-factories> diff --git a/java/jca/example/conf/web.xml b/java/jca/example/conf/web.xml new file mode 100644 index 0000000000..509612dc90 --- /dev/null +++ b/java/jca/example/conf/web.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + - + - 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. + - + --> +<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> + + <resource-ref> + <res-ref-name>QpidJMSXA</res-ref-name> + <res-type>javax.jms.ConnectionFactory</res-type> + <res-auth>Container</res-auth> + <res-sharing-scope>Shareable</res-sharing-scope> + </resource-ref> + + <ejb-local-ref> + <ejb-ref-name>QpidTestBean</ejb-ref-name> + <ejb-ref-type>Session</ejb-ref-type> + <local>org.apache.qpid.jca.example.ejb.QpidTestLocal</local> + </ejb-local-ref> + + <servlet> + <display-name>QpidTestServlet</display-name> + <servlet-name>QpidTestServlet</servlet-name> + <servlet-class>org.apache.qpid.jca.example.web.QpidTestServlet</servlet-class> + <load-on-startup>1</load-on-startup> + </servlet> + + <servlet-mapping> + <servlet-name>QpidTestServlet</servlet-name> + <url-pattern>/qpid</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 new file mode 100644 index 0000000000..ee0478a6e5 --- /dev/null +++ b/java/jca/example/qpid-jca-example-properties.xml @@ -0,0 +1,79 @@ +<!-- + - + - 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-properties" basedir="." default=""> + + <property name="src.dir" location="${basedir}/src/main/java"/> + <property name="lib.dir" location="${basedir}/lib"/> + <property name="conf.dir" location="${basedir}/conf"/> + <property name="build.dir" location="${basedir}/build"/> + <property name="build.classes.dir" location="${build.dir}/classes"/> + <property name="gen.dir" location="${build.dir}/gen"/> + <property name="log.dir" location="${build.dir}/log"/> + <property name="qpid.jca.dir" location="${env.QPID_JCA_HOME}"/> + + <property name="ejb.name" value="qpid-jcaex-ejb.jar"/> + <property name="war.name" value="qpid-jcaex-web.war"/> + <property name="ear.name" value="qpid-jcaex.ear"/> + + <property name="rar.ver" value="${qpid.ver}"/> + <property name="rar.name" value="qpid-ra-${rar.ver}.rar"/> + + <property name="broker.url" value="amqp://anonymous:passwd@client/test?brokerlist='tcp://${broker.address}?sasl_mechs='ANONYMOUS''"/> + + <property name="qpid.hello.topic.dest.address.ADDR" value="amq.topic/hello.Topic"/> + <property name="qpid.goodbye.topic.dest.address.ADDR" value="amq.topic/goodbye.Topic"/> + <property name="qpid.hellogoodbye.topic.dest.address.ADDR" value="amq.topic/goodbye.Topic"/> + <property name="qpid.hello.queue.dest.address.ADDR" + 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.hello.topic.dest.address.BURL" + value="topic://amq.topic//hello.jcaTopic?routingKey='hello.jcaTopic',autodelete='true'"/> + <property name="qpid.goodbye.topic.dest.address.BURL" + value="topic://amq.topic//goodbye.jcaTopic?routingKey='goodbye.jcaTopic',autodelete='true'"/> + <property name="qpid.hellogoodbye.topic.dest.address.BURL" + value="topic://amq.topic//#.jcaTopic"/> + <property name="qpid.hello.queue.dest.address.BURL" + value="direct://amq.direct//hello.Queue?routingkey='hello.Queue'"/> + <property name="qpid.goodbye.queue.dest.address.BURL" + value="direct://amq.direct//goodbye.Queue?routingkey='goodbye.Queue'"/> + <property name="qpid.responder.queue.dest.address.BURL" + value="direct://amq.direct//responder.Queue?routingkey='responder.Queue'"/> + + <!-- This macro allows us to construct a property name which contains a property expansion --> + <macrodef name="set-address-property"> + <attribute name="name"/> + <attribute name="syntax"/> + <sequential> + <property name="@{name}" value="${@{name}.@{syntax}}"/> + </sequential> + </macrodef> + + <set-address-property name="qpid.hello.topic.dest.address" syntax="${qpid.dest_syntax}"/> + <set-address-property name="qpid.goodbye.topic.dest.address" syntax="${qpid.dest_syntax}"/> + <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}"/> +</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 new file mode 100644 index 0000000000..734df1c0f3 --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/client/QpidRequestResponseClient.java @@ -0,0 +1,159 @@ +/* + * + * 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.client; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.InitialContext; + +import org.apache.qpid.jca.example.ejb.QpidUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +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_MESSAGE = "Hello, World!"; + private static final int DEFAULT_MESSAGE_COUNT = 1; + private static final int DEFAULT_THREAD_COUNT = 1; + private static CountDownLatch THREAD_LATCH; + private static InitialContext CONTEXT; + + private ConnectionFactory _connectionFactory; + private Connection _connection; + private Session _session; + private CountDownLatch _latch = null; + private int _count = DEFAULT_MESSAGE_COUNT; + + /** + * @param args + */ + public static void main(String[] args) throws Exception + { + int threadCount = (System.getProperty("thread.count") == null) + ? DEFAULT_THREAD_COUNT : Integer.valueOf(System.getProperty("thread.count")); + + _log.debug("Creating " + threadCount + " threads for execution."); + + THREAD_LATCH = new CountDownLatch(threadCount); + + CONTEXT = new InitialContext(); + + for(int i = 0; i < threadCount; i++) + { + new Thread(new QpidRequestResponseClient()).start(); + } + + _log.debug("Waiting for " + threadCount + " to finish."); + THREAD_LATCH.await(10, TimeUnit.SECONDS); + + QpidUtil.closeResources(CONTEXT); + } + + @Override + public void onMessage(Message message) + { + _latch.countDown(); + + if(message instanceof TextMessage) + { + try + { + _log.debug("Thread " + Thread.currentThread().getId() + " received response message with content " + ((TextMessage)message).getText()); + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + } + } + + if(_latch.getCount() == _count) + { + QpidUtil.closeResources(_session, _connection); + } + + THREAD_LATCH.countDown(); + + } + + public void run() + { + MessageProducer producer = null; + Destination requestQueue = null; + Destination responseQueue = null; + + String cfName = (System.getProperty("qpid.cf.name") == null) ? DEFAULT_CF_JNDI : System.getProperty("qpid.cf.name"); + String destName = (System.getProperty("qpid.dest.name") == null) ? DEFAULT_DESTINATION_JNDI : System.getProperty("qpid.dest.name"); + + try + { + _count = (System.getProperty("message.count") == null) ? DEFAULT_MESSAGE_COUNT : Integer.valueOf(System.getProperty("message.count")); + _latch = new CountDownLatch(_count); + + _connectionFactory = (ConnectionFactory)QpidTestUtil.getFromJNDI(CONTEXT, cfName); + requestQueue = (Destination)QpidTestUtil.getFromJNDI(CONTEXT, destName); + _connection = _connectionFactory.createConnection(); + _session = _connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + producer = _session.createProducer(requestQueue); + responseQueue = _session.createTemporaryQueue(); + _session.createConsumer(responseQueue).setMessageListener(this); + + + _connection.start(); + + String content = (System.getProperty("qpid.message") == null) ? DEFAULT_MESSAGE : System.getProperty("qpid.message"); + + for(int i = 0; i < _count; i++) + { + TextMessage message = _session.createTextMessage(); + message.setText(content); + message.setJMSReplyTo(responseQueue); + producer.send(message); + + } + + _latch.await(); + + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + } + finally + { + QpidUtil.closeResources(producer); + } + + } + +} diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/client/QpidTestClient.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/client/QpidTestClient.java new file mode 100644 index 0000000000..a5a33e36ec --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/client/QpidTestClient.java @@ -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. + * + */ +package org.apache.qpid.jca.example.client; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.Context; +import javax.naming.InitialContext; + +import org.apache.qpid.jca.example.ejb.QpidTest; +import org.apache.qpid.jca.example.ejb.QpidUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class QpidTestClient +{ + private static final Logger _log = LoggerFactory.getLogger(QpidTestClient.class); + + private static final String DEFAULT_EJB_JNDI = "QpidTestBean/remote"; + private static final String DEFAULT_CF_JNDI = "QpidConnectionFactory"; + private static final String DEFAULT_MESSAGE = "Hello,World!"; + private static final int DEFAULT_MESSAGE_COUNT = 1; + private static final boolean DEFAULT_USE_TOPIC = false; + private static final boolean DEFAULT_USE_EJB = true; + private static final String DEFAULT_DESTINATION_JNDI = "HelloQueue"; + private static final boolean DEFAULT_SAY_GOODBYE = false; + + public static void main(String[] args) throws Exception + { + String content = (System.getProperty("qpid.message") == null) ? DEFAULT_MESSAGE : System.getProperty("qpid.message"); + boolean useEJB = (System.getProperty("use.ejb") == null) ? DEFAULT_USE_EJB : Boolean.valueOf(System.getProperty("use.ejb")); + int total = (System.getProperty("message.count") == null) ? DEFAULT_MESSAGE_COUNT : Integer.valueOf(System.getProperty("message.count")); + boolean useTopic = (System.getProperty("use.topic") == null) ? DEFAULT_USE_TOPIC : Boolean.valueOf(System.getProperty("use.topic")); + String destType = (useTopic) ? "Topic" : "Queue"; + boolean goodbye = (System.getProperty("say.goodbye") == null) ? DEFAULT_SAY_GOODBYE : Boolean.valueOf(System.getProperty("say.goodbye")); + + _log.debug("Environment: "); + _log.debug("JNDI IntialContectFactory: " + System.getProperty("java.naming.factory.initial")); + _log.debug("JNDI Provider: " + System.getProperty("java.naming.provider.url")); + _log.debug("Message content: " + content); + _log.debug("Message count:" + total); + _log.debug("Protocol: " + ((useEJB) ? "EJB" : "JMS")); + _log.debug("Destination Type: " + destType); + _log.debug("Say GoodBye : " + goodbye); + + Context context = new InitialContext(); + + if(useEJB) + { + + String ejbName = (System.getProperty("qpid.ejb.name") == null) ? DEFAULT_EJB_JNDI : System.getProperty("qpid.ejb.name"); + + QpidTest ejb = (QpidTest)QpidTestUtil.getFromJNDI(context, ejbName); + + _log.debug("Found SLSB " + ejbName + "in JNDI"); + ejb.testQpidAdapter(content, total, useTopic, false, goodbye); + + } + else + { + ConnectionFactory connectionFactory = null; + Connection connection = null; + Session session = null; + MessageProducer messageProducer = null; + Destination destination = null; + int count = 0; + + String cfName = (System.getProperty("qpid.cf.name") == null) ? DEFAULT_CF_JNDI : System.getProperty("qpid.cf.name"); + String destName = (System.getProperty("qpid.dest.name") == null) ? DEFAULT_DESTINATION_JNDI : System.getProperty("qpid.dest.name"); + + _log.debug("Using JMS with CF name " + cfName + " and Destination name " + destName + " to send " + total + " message(s) with content " + content); + + try + { + _log.debug("Using JNDI at " + System.getProperty("java.naming.provider.url")); + + connectionFactory = (ConnectionFactory)QpidTestUtil.getFromJNDI(context, cfName); + destination = (Destination)QpidTestUtil.getFromJNDI(context, destName); + + _log.debug("Using CF: " + connectionFactory); + _log.debug("Destination " + destination); + + connection = connectionFactory.createConnection(); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + messageProducer = session.createProducer(destination); + + _log.debug("Sending " + total + " message(s) with content: " + content + " to destination " + destName); + + for(int i = 0; i < total; i++) + { + TextMessage message = session.createTextMessage(content); + message.setBooleanProperty("say.goodbye", goodbye); + messageProducer.send(message); + count++; + } + + + } + catch(Exception e) + { + e.printStackTrace(); + _log.error(e.getMessage()); + } + finally + { + QpidUtil.closeResources(session, connection, context); + } + + _log.debug(count + " message(s) sent successfully"); + } + + } +} diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/client/QpidTestUtil.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/client/QpidTestUtil.java new file mode 100644 index 0000000000..7a53335d79 --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/client/QpidTestUtil.java @@ -0,0 +1,52 @@ +/* + * + * 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.client; + +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.Reference; +import javax.naming.spi.NamingManager; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class QpidTestUtil { + private static final Logger _log = LoggerFactory.getLogger(QpidTestUtil.class); + + /* + * Encapsulate looking up in JNDI and working around a seeming bug in OpenEJB which returns a + * Reference when it should just return an object constructed from it + */ + static Object getFromJNDI(Context context, String name) throws NamingException, Exception + { + Object o = context.lookup(name); + if (o instanceof Reference) + { + _log.debug("Got a Reference back from JNDI for " + name + " - working around"); + return NamingManager.getObjectInstance(o, null, null, null); + } + else + { + return o; + } + } + +} 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 new file mode 100644 index 0000000000..9cf220de2a --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidGoodByeListenerBean.java @@ -0,0 +1,65 @@ +/* + * + * 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.ejb; + +import java.util.Date; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.TextMessage; + +import org.slf4j.Logger; +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 = "connectionURL", propertyValue = "@broker.url@"), + @ActivationConfigProperty(propertyName = "useLocalTx", propertyValue = "false"), + @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "10") +}) +public class QpidGoodByeListenerBean implements MessageListener +{ + private static final Logger _log = LoggerFactory.getLogger(QpidGoodByeListenerBean.class); + + @Override + public void onMessage(Message message) + { + try + { + if(message instanceof TextMessage) + { + String content = ((TextMessage)message).getText(); + + _log.info("Received text message with contents: [" + content + "] at " + new Date()); + } + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + } + + } + +} 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 new file mode 100644 index 0000000000..8ad8aaa482 --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidGoodByeSubscriberBean.java @@ -0,0 +1,27 @@ +package org.apache.qpid.jca.example.ejb; + +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.Message; +import javax.jms.MessageListener; + +@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 = "connectionURL", propertyValue = "@broker.url@"), + @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "NotDurable"), + @ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "hello.Topic"), + @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "10") +}) + +public class QpidGoodByeSubscriberBean implements MessageListener +{ + + @Override + public void onMessage(Message message) + { + System.out.println(message); + } + +} 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 new file mode 100644 index 0000000000..d6d08d1557 --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidHelloListenerBean.java @@ -0,0 +1,118 @@ +/* + * + * 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.ejb; + +import java.util.Date; + +import javax.annotation.PostConstruct; +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; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.InitialContext; + +import org.slf4j.Logger; +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 = "connectionURL", propertyValue = "@broker.url@"), + @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "10") +}) +public class QpidHelloListenerBean implements MessageListener +{ + private static final Logger _log = LoggerFactory.getLogger(QpidHelloListenerBean.class); + + private ConnectionFactory _connectionFactory; + + private Destination _queue; + + @PostConstruct + public void init() + { + InitialContext context = null; + + try + { + context = new InitialContext(); + _connectionFactory = (ConnectionFactory)context.lookup("java:comp/env/QpidJMSXA"); + _queue = (Destination)context.lookup("@qpid.goodbye.queue.jndi.name@"); + + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + } + finally + { + QpidUtil.closeResources(context); + } + + } + + @Override + public void onMessage(Message message) + { + Connection connection = null; + Session session = null; + MessageProducer messageProducer = null; + TextMessage response = null; + + try + { + if(message instanceof TextMessage) + { + String content = ((TextMessage)message).getText(); + + _log.info("Received text message with contents: [" + content + "] at " + new Date()); + + StringBuffer temp = new StringBuffer(); + temp.append("QpidHelloListenerBean received message with content: [" + content); + temp.append("] at " + new Date()); + + if(message.propertyExists("say.goodbye") && message.getBooleanProperty("say.goodbye")) + { + connection = _connectionFactory.createConnection(); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + messageProducer = session.createProducer(_queue); + response = session.createTextMessage(temp.toString()); + messageProducer.send(response); + } + } + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + } + finally + { + QpidUtil.closeResources(session, connection); + } + } +} 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 new file mode 100644 index 0000000000..43ccf9defd --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidHelloSubscriberBean.java @@ -0,0 +1,121 @@ +/* + * + * 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.ejb; + +import java.util.Date; + +import javax.annotation.PostConstruct; +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; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.InitialContext; + +import org.slf4j.Logger; +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 = "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 +{ + private static final Logger _log = LoggerFactory.getLogger(QpidHelloSubscriberBean.class); + + private ConnectionFactory _connectionFactory; + + private Destination _topic; + + @PostConstruct + public void init() + { + InitialContext context = null; + + try + { + context = new InitialContext(); + _connectionFactory = (ConnectionFactory)context.lookup("java:comp/env/QpidJMSXA"); + _topic = (Destination)context.lookup("@qpid.goodbye.topic.jndi.name@"); + + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + } + finally + { + QpidUtil.closeResources(context); + } + + } + + @Override + public void onMessage(Message message) + { + Connection connection = null; + Session session = null; + MessageProducer messageProducer = null; + TextMessage response = null; + + try + { + if(message instanceof TextMessage) + { + String content = ((TextMessage)message).getText(); + + _log.info("Received text message with contents: [" + content + "] at " + new Date()); + + StringBuffer temp = new StringBuffer(); + temp.append("QpidHelloSubscriberBean received message with content: [" + content); + temp.append("] at " + new Date()); + + if(message.propertyExists("say.goodbye") && message.getBooleanProperty("say.goodbye")) + { + connection = _connectionFactory.createConnection(); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + messageProducer = session.createProducer(_topic); + response = session.createTextMessage(temp.toString()); + messageProducer.send(response); + } + } + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + } + finally + { + QpidUtil.closeResources(session, connection); + } + } +} 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 new file mode 100644 index 0000000000..74d6fb6d89 --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidJMSResponderBean.java @@ -0,0 +1,100 @@ +package org.apache.qpid.jca.example.ejb; + +import java.util.Date; + +import javax.annotation.PostConstruct; +import javax.ejb.ActivationConfigProperty; +import javax.ejb.MessageDriven; +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.InitialContext; + +import org.slf4j.Logger; +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 = "connectionURL", propertyValue = "@broker.url@"), + @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "10") +}) +public class QpidJMSResponderBean implements MessageListener +{ + + private static final Logger _log = LoggerFactory.getLogger(QpidJMSResponderBean.class); + + private ConnectionFactory _connectionFactory; + + @PostConstruct + public void init() + { + InitialContext context = null; + + try + { + context = new InitialContext(); + _connectionFactory = (ConnectionFactory)context.lookup("java:comp/env/QpidJMSXA"); + + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + } + finally + { + QpidUtil.closeResources(context); + } + + } + + @Override + public void onMessage(Message message) + { + Connection connection = null; + Session session = null; + MessageProducer messageProducer = null; + TextMessage response = null; + + try + { + if(message instanceof TextMessage) + { + String content = ((TextMessage)message).getText(); + + _log.info("Received text message with contents: [" + content + "] at " + new Date()); + + StringBuffer temp = new StringBuffer(); + temp.append("QpidJMSResponderBean received message with content: [" + content); + temp.append("] at " + new Date()); + + if(message.getJMSReplyTo() != null) + { + connection = _connectionFactory.createConnection(); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + messageProducer = session.createProducer(message.getJMSReplyTo()); + response = session.createTextMessage(); + response.setText(temp.toString()); + messageProducer.send(response); + } + else + { + _log.warn("Response was requested with no JMSReplyToDestination set. Will not respond to message."); + } + } + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + } + finally + { + QpidUtil.closeResources(session, connection); + } + } +} diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTest.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTest.java new file mode 100644 index 0000000000..14488fda53 --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTest.java @@ -0,0 +1,30 @@ +/* + * + * 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.ejb; + +public interface QpidTest +{ + public void testQpidAdapter(String content) throws Exception; + public void testQpidAdapter(String content, int count) throws Exception; + public void testQpidAdapter(String content, int count, boolean useTopic) throws Exception; + public void testQpidAdapter(String content, int count, boolean useTopic, boolean respond, boolean sayGoodbye) throws Exception; +} 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 new file mode 100644 index 0000000000..17e37b9475 --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTestBean.java @@ -0,0 +1,123 @@ +/* + * + * 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.ejb; + +import javax.annotation.PostConstruct; +import javax.ejb.Stateless; +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.InitialContext; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Stateless +public class QpidTestBean implements QpidTestRemote, QpidTestLocal +{ + + private static final Logger _log = LoggerFactory.getLogger(QpidTestBean.class); + + private ConnectionFactory _connectionFactory; + + private Destination _queue; + + private Destination _topic; + + @PostConstruct + public void init() + { + InitialContext context = null; + + try + { + context = new InitialContext(); + _connectionFactory = (ConnectionFactory)context.lookup("java:comp/env/QpidJMSXA"); + _queue = (Destination)context.lookup("@qpid.hello.queue.jndi.name@"); + _topic = (Destination)context.lookup("@qpid.hello.topic.jndi.name@"); + + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + } + finally + { + QpidUtil.closeResources(context); + } + + } + @Override + public void testQpidAdapter(String content) throws Exception + { + testQpidAdapter(content, 1); + } + + @Override + public void testQpidAdapter(String content, int count) throws Exception + { + testQpidAdapter(content, count, false); + } + + public void testQpidAdapter(final String content, int count, boolean useTopic) throws Exception + { + testQpidAdapter(content, count, useTopic, false, false); + } + + @Override + public void testQpidAdapter(String content, int count, boolean useTopic, + boolean respond, boolean sayGoodbye) throws Exception + { + Connection connection = null; + Session session = null; + MessageProducer messageProducer = null; + + _log.info("Sending " + count + " message(s) to MDB with content " + content); + + try + { + connection = _connectionFactory.createConnection(); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + messageProducer = (useTopic) ? session.createProducer(_topic) : session.createProducer(_queue); + + for(int i = 0; i < count; i++) + { + TextMessage message = session.createTextMessage(content); + message.setBooleanProperty("say.goodbye", sayGoodbye); + messageProducer.send(message); + } + + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + throw e; + } + finally + { + QpidUtil.closeResources(messageProducer, session, connection); + } + } + +} diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTestLocal.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTestLocal.java new file mode 100644 index 0000000000..73a0de08c2 --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTestLocal.java @@ -0,0 +1,29 @@ +/* + * + * 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.ejb; + +import javax.ejb.Local; + +@Local +public interface QpidTestLocal extends QpidTest +{ +} diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTestRemote.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTestRemote.java new file mode 100644 index 0000000000..2abb4d71f5 --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidTestRemote.java @@ -0,0 +1,29 @@ +/* + * + * 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.ejb; + +import javax.ejb.Remote; + +@Remote +public interface QpidTestRemote extends QpidTest +{ +} diff --git a/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidUtil.java b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidUtil.java new file mode 100644 index 0000000000..d96a4e8163 --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/ejb/QpidUtil.java @@ -0,0 +1,90 @@ +/* + * + * 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.ejb; + +import java.lang.reflect.Method; +import java.util.Enumeration; + +import javax.jms.Message; +import javax.jms.TextMessage; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class QpidUtil +{ + private static final Logger _log = LoggerFactory.getLogger(QpidTestBean.class); + + public static void handleMessage(String beanName, final Message message) throws Exception + { + if(message instanceof TextMessage) + { + String content = ((TextMessage)message).getText(); + _log.debug(beanName + ": Received text message with contents " + content); + + if(content.contains("PrintEnv")) + { + printJMSHeaders(message); + printProperties(message); + } + } + } + + @SuppressWarnings("rawtypes") + public static void printProperties(final Message message) throws Exception + { + _log.debug("Priting Message Properties:"); + + Enumeration e = message.getPropertyNames(); + + while(e.hasMoreElements()) + { + _log.debug(e + ":" + message.getObjectProperty(e.toString())); + } + } + + public static void printJMSHeaders(final Message message) throws Exception + { + _log.debug("JMSCorrelationID:" + message.getJMSCorrelationID()); + _log.debug("JMSDeliveryMode:" + message.getJMSDeliveryMode()); + _log.debug("JMSExpires:" + message.getJMSExpiration()); + _log.debug("JMSMessageID:" + message.getJMSMessageID()); + _log.debug("JMSPriority:" + message.getJMSPriority()); + _log.debug("JMSTimestamp:" + message.getJMSTimestamp()); + _log.debug("JMSType:" + message.getJMSType()); + _log.debug("JMSReplyTo:" + message.getJMSReplyTo()); + } + + public static void closeResources(Object...objects) + { + try + { + for(Object object: objects) + { + Method close = object.getClass().getMethod("close", new Class[]{}); + close.invoke(object, new Object[]{}); + } + } + catch(Exception ignore) + { + } + } +} 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 new file mode 100644 index 0000000000..71289b22c3 --- /dev/null +++ b/java/jca/example/src/main/java/org/apache/qpid/jca/example/web/QpidTestServlet.java @@ -0,0 +1,209 @@ +/* + * + * 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 javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +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 QpidTestServlet 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_TOPIC = false; + private static final boolean DEFAULT_XA = false; + private static final boolean DEFAULT_SAY_GOODBYE = true; + + private ConnectionFactory _connectionFactory; + + private Destination _queue; + + private Destination _topic; + + public void init(ServletConfig config) throws ServletException + { + + InitialContext context = null; + + try + { + context = new InitialContext(); + _connectionFactory = (ConnectionFactory)context.lookup("java:comp/env/QpidJMSXA"); + _queue = (Destination)context.lookup("@qpid.hello.queue.jndi.name@"); + _topic = (Destination)context.lookup("@qpid.hello.topic.jndi.name@"); + + } + catch(Exception e) + { + _log.error(e.getMessage(), e); + throw new ServletException(e.getMessage(), e); + } + finally + { + QpidUtil.closeResources(context); + } + } + + @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; + + try + { + String content = (req.getParameter("message") == null) ? DEFAULT_MESSAGE : req.getParameter("message"); + boolean useEJB = (req.getParameter("useEJB") == null) ? false : Boolean.valueOf(req.getParameter("useEJB")); + 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")); + ctx = new InitialContext(); + boolean sayGoodBye = (req.getParameter("sayGoodBye") == null) ? DEFAULT_SAY_GOODBYE : Boolean.valueOf(req.getParameter("sayGoodBye")); + + _log.debug("Environment: "); + _log.debug("Message content: " + content); + _log.debug("Message count:" + count); + _log.debug("Protocol: " + ((useEJB) ? "EJB" : "JMS")); + _log.debug("Destination Type: " + ((useTopic) ? "Topic" : "Queue")); + _log.debug("Using XA: " + useXA); + _log.debug("Say GoodBye: ", sayGoodBye); + + resp.getOutputStream().println("Environment: "); + resp.getOutputStream().println("Message content: " + content); + resp.getOutputStream().println("Message count:" + count); + resp.getOutputStream().println("Protocol: " + ((useEJB) ? "EJB" : "JMS")); + resp.getOutputStream().println("Destination Type: " + ((useTopic) ? "Topic" : "Queue")); + resp.getOutputStream().println("Using XA: " + useXA); + resp.getOutputStream().println("Say GoodBye: " + sayGoodBye); + + if(useEJB) + { + QpidTest ejb = (QpidTest)ctx.lookup("java:comp/env/QpidTestBean"); + ejb.testQpidAdapter(content, count, useTopic, false, sayGoodBye); + } + else + { + if(useXA) + { + ut = (UserTransaction)ctx.lookup("java:comp/UserTransaction"); + ut.begin(); + } + + connection = _connectionFactory.createConnection(); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + messageProducer = (useTopic) ? session.createProducer(_topic) : session.createProducer(_queue); + + for(int i = 0; i < count; i++) + { + TextMessage message = session.createTextMessage(content); + message.setBooleanProperty("say.goodbye", sayGoodBye); + messageProducer.send(message); + } + + } + + resp.getOutputStream().println("Sent " + count + " messages with content '" + content + "'"); + resp.getOutputStream().flush(); + + } + catch(Exception e) + { + + if(useXA && ut != null) + { + try + { + rollback = true; + ut.setRollbackOnly(); + } + 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); + } + 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); + + } + } + + QpidUtil.closeResources(session, connection, ctx); + } + } + + + +} + + |