Consume Topic messages from remote MDB - ActiveMQ 5.5.1 & Glassfish 3.1.1

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Consume Topic messages from remote MDB - ActiveMQ 5.5.1 & Glassfish 3.1.1

amb_enthusiast
This post has NOT been accepted by the mailing list yet.
Hello ActiveMQ community,

I am a newbie to the ActiveMQ and Glassfish world, and after working with OpenMQ and Glassfish with small successes, I wanted to learn about ActiveMQ in order to develop a message processing application.

I am seeking to deploy a message-driven bean to Glassfish 3.1.1 which consumes messages from a destination (Topic) hosted on a remote ActiveMQ broker. To mimic this, I have installed two "clean" default installations:

1. ActiveMQ (tcp://localhost:61616, admin http//:localhost:8161)
2. Glassfish (http://localhost:8080, admin http://localhost:4848).

I have attempted to work through several old (Glassfish 2 and ActiveMQ 4!) tutorials relating to this setup:

http://www.java.net/node/673509
http://weblogs.java.net/blog/rampsarathy/archive/2007/03/glassfish_v2_an.html

sadly, I have had zero success - getting a remote MDB to consume messages has not worked out.

Setting up ActiveMQ 5.5.1

Getting ActiveMQ up and running with a Topic (jms/activemq/testTopic) and durable subscriber (clientId = testClientID and subscriberId = testSubscriberID) was straight-forward. Similarly, creating a simple producer client which sends 10 TextMessages to the ActiveMQ jms/activemq/topic destination (via JNDI lookup to get a ConnectionFactory) was straight-forward.

Using resource adapters in Gassfish 3.1.1

I have deployed the activemq-rar-5.5.1.rar to Glassfish, configure to point to the ActiveMQ broker, defined ConnectionPool and Connector resources for the ra, and created an administered object Topic (with JNDI name jms/activemq/topic). All the activeMQ libs were added to the domain1/libs/ext directory.

I then create a simple MDB, annotated with the jms/activemq/topic and clientID and subscriberID values. The onMessage() method simply prints out the content of a TextMessage to the standard output.

I can deploy the MDB application without throwing any exceptions, however no messages are consumed by the MDB; the jms/activemq/topic destination message count remains static, and no active connections are shown in the admin console.

I have had a similar experience when trying to use the genericra.jar.

I wondered whether anyone has experience working with the latest stable release of ActiveMQ (5.5.1) and Glassfish 3.1.1 in this configuration? If so, what are the steps necessary to use either activemq resource adapter or genericra resource adapter to enable remote consumption?

Apologies if this is more of a Glassfish configuration question... I just wanted to see if anyone has worked through this before, or if any experienced developers can offer advice.

Of course, if posting code/config files helps, let me know.

Thanks in advance,

Ant
Reply | Threaded
Open this post in threaded view
|

Re: Consume Topic messages from remote MDB - ActiveMQ 5.5.1 & Glassfish 3.1.1

amb_enthusiast
Hi community,

After more reading, trial and error and thinking I managed to get this setup working.  I thought I would share my efforts, in case anyone would like to make use of it.


Set up some test resources on the ActiveMQ server

Create a topic on Activemq called jms/activemq/topic.  Next, create a durable subscriber (clientId = clientID, subscriptionName = subscriberId.  for illustration, the broker is located at tcp://2.2.2.2:61616.


Configure the activemq-rar-5.5.1.rar file

I found it best to edit the ra.xml in the activemq-rar-5.5.1.rar in order to set correct properties.  This meant:
1) Setting the serverUrl property to the location of the remote message broker (tcp://2.2.2.2:61616)
2) Removing the the config property relating to the embedded broker usecase (as noted by in-file comments)


Copy ActiveMQ libs to Glassfish

Next, copy the following libraries:

log4j-1.2.14.jar
slf4j-api-1.5.11.jar
slf4j-log4j12-1.5.11.jar

from the activemq distro/libs directory to the <glassfishInstall>/<domain>/lib directory

Deploy the activemq-rar-5.5.1.rar via the Glassfih admin console (Application > Deploy)


Configure Glassfish resource adapter & connection resources

I used the admin console to:

1) Create a new resource adapter via Resource Adapter Configs menu

2) Create a new ConnectionPool for the activemq-rar-5.5.1 resource adapter

3) Create a new Connector resource from the activemq ConnectionPool (e.g. jms/activemq/connector for jndi name)

4) Create a new admin object, corresponding to the jms destination on the remote activemq broker (in our case jms/activemq/topic).  Make sure you select the activemq resource adapter from the drop down list, and set a physical name.


Build an MDB project

I used Netbeans (7.0.1) to create a new EAR application, and within it a EJB module.

Within the EJB module, I created a new MDB, within a mq.beans package.  The MDB code simply writes out the content of a textmessage to the standard output (the Glassfish server log).  See code below.

Note the annotations, which provide clientId and subsriptionName values which correspond to the durable subscriber details we created in ActiveMQ, and that the mdb is mapped to the Glassfish admin object jms/activemq/topic, which is mapped to the activeMq topic by the jndi name.

Source code for simple MDB:

****MqTopicMdb.java***

package mq.beans;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

/**
 *
 * @author Ant
 */
@MessageDriven(mappedName = "jms/activemq/topic", activationConfig = {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
    @ActivationConfigProperty(propertyName = "subscriptionDurability", propertyValue = "Durable"),
    @ActivationConfigProperty(propertyName = "clientId", propertyValue = "clientID"),
    @ActivationConfigProperty(propertyName = "subscriptionName", propertyValue = "subscriberID")
})
public class MqTopicMdb implements MessageListener {
   
    public MqTopicMdb() {
    }

    private int count = 0;

    @Override
    public void onMessage(Message message) {
        try {
            count = count + 1;
            File msgFile = new File("C:\\someUser\\Desktop\\activeMQ msgs\\activeMqMessage" + count + ".txt");
            FileWriter writer = new FileWriter(msgFile);
            // get a textMessage
            if (message instanceof TextMessage) {
                TextMessage txtMsg = (TextMessage) message;
                System.out.println("Received text message " + count + " from activeMQ:\n" + txtMsg.getText());
                writer.write("Message " + count + ":\n" + txtMsg.getText());
                writer.close();
            } else {
                System.out.println("Received a message, it just isnt a textMessage!");
                writer.write("Message " + count +" received at " + String.valueOf(System.currentTimeMillis()));
                writer.close();
            }
        } catch (IOException ioe) {
            System.out.println("There was an error creating and writing to the file. Try a different filepath.\n" + ioe.getCause());
        } catch (JMSException jmse) {
            System.out.println("There was a error with the JMS");
            jmse.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


Create deployment descriptors for MDB

This was the missing step in my previous efforts - creating appropriate deployment descriptor resources for the application - ejb.jar.xml and glassfish-ejb-jar.xml - is essential.

****ejb-jar.xml****

<?xml version="1.0" encoding="UTF-8"?>

<ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee" 
         version = "3.1"
         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_1.xsd">
<enterprise-beans>
    <message-driven>       
           <ejb-name>MqTopicMdb</ejb-name>
           <ejb-class>mq.beans.MqTopicMdb</ejb-class>           
    </message-driven>   
</enterprise-beans>
<assembly-descriptor>   
       <container-transaction>       
        <method>           
            <ejb-name>MqTopicMdb</ejb-name>
            <method-name>onMessage</method-name>           
                <method-params>                   
                    <method-param>javax.jms.Message</method-param>                   
                </method-params>           
        </method>       
       <trans-attribute>Required</trans-attribute>       
       </container-transaction>       
</assembly-descriptor>
</ejb-jar>

*****glassfish-ejb-jar.xml*****

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-ejb-jar PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 EJB 3.1//EN" "http://glassfish.org/dtds/glassfish-ejb-jar_3_1-
1.dtd">
<glassfish-ejb-jar>   
  <enterprise-beans>     
    <ejb>       
      <ejb-name>MqTopicMdb</ejb-name>     
      <mdb-resource-adapter>     
      <resource-adapter-mid>activemq-rar-5.5.1</resource-adapter-mid>
     
      <activation-config>
      <activation-config-property>
          <activation-config-property-name>destination</activation-config-property-name>
          <activation-config-property-value>jms/activemq/topic</activation-config-property-value>
      </activation-config-property>

       <activation-config-property>
           <activation-config-property-name>destinationType</activation-config-property-name>
           <activation-config-property-value>javax.jms.Topic</activation-config-property-value>
       </activation-config-property>
       </activation-config>
      </mdb-resource-adapter>   
    </ejb>
  </enterprise-beans>
</glassfish-ejb-jar>


Deploy the application to the glassfish server, and inspect the server log.  You should see output similar to:

INFO: 2012-01-23 23:38:31,519 [ad-pool-4848(3)] INFO  ActiveMQEndpointWorker         - Starting
INFO: 2012-01-23 23:38:31,539 [d-pool-1; w: 20] INFO  ActiveMQEndpointWorker         - Establishing connection to broker [tcp://2.2.2.2:61616]
INFO: 2012-01-23 23:38:31,666 [d-pool-1; w: 20] INFO  ActiveMQEndpointWorker         - Successfully established connection to broker [tcp://2.2.2.2:61616]
INFO: ActiveMqMdb_app was successfully deployed in 652 milliseconds.


Create a simple producer

For testing purposes, I also wrote a simple client producer which sends a TextMessage to the jms/activemq/topic destination every 3 seconds:

*****JMSClientProducer.java*****

package jmsclientproducer;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnectionFactory;

/**
 *
 * @author Ant
 */
public class JMSClientProducer {

    public static void main(String[] args) {
        try {
            HashMap<String, String> props = new HashMap<String, String>();
             ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://2.2.2.2:61616");
             
             Connection connection = connectionFactory.createConnection();
             
             Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
             
             Destination destination = session.createTopic("jms/activemq/topic");
             
             MessageProducer producer = session.createProducer(destination);
             
             connection.start();
             TextMessage txtMsg;
             for (int a = 1; a <= 200; a++) {
                Thread.sleep(2000);
                 
                txtMsg = session.createTextMessage();
                System.out.println("Sending message " + a + " ...");
                Date now = new Date(System.currentTimeMillis());
                DateFormat format = DateFormat.getDateTimeInstance();
                String nowString = format.format(now);
               
                txtMsg.setText("***TextMessage:: " + a + "\ndateTime = " + nowString + "\nMilliseconds = " + System.currentTimeMillis() + "\n This is a test message, set from a standalone client to the ActiveMQ broker,  jms/activeMq/testTopic destination\n***");
                producer.send(txtMsg);
                System.out.println("Completed send for  message " + a + " ...\n");
               
             }
             
             connection.stop();
             
             System.exit(1);
           
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}

The activemq-all-5.5.1.jar, activemq-core-5.5.1.jar, slf4j-api.jar, slf4j-log4j-1.2.14.jar and log4j-1.2.14.jar libraries from the activemq/lib directory were added to the client project build path.


Cheers,

Ant
Reply | Threaded
Open this post in threaded view
|

Re: Consume Topic messages from remote MDB - ActiveMQ 5.5.1 & Glassfish 3.1.1

gtully
Thank you :-)

On 24 January 2012 07:07, amb_enthusiast <[hidden email]> wrote:

> Hi community,
>
> After more reading, trial and error and thinking I managed to get this setup
> working.  I thought I would share my efforts, in case anyone would like to
> make use of it.
>
>
> *Set up some test resources on the ActiveMQ server*
>
> Create a topic on Activemq called jms/activemq/topic.  Next, create a
> durable subscriber (clientId = clientID, subscriptionName = subscriberId.
> for illustration, the broker is located at tcp://2.2.2.2:61616.
>
>
> *Configure the activemq-rar-5.5.1.rar file*
>
> I found it best to edit the ra.xml in the activemq-rar-5.5.1.rar in order to
> set correct properties.  This meant:
> 1) Setting the serverUrl property to the location of the remote message
> broker (tcp://2.2.2.2:61616)
> 2) Removing the the config property relating to the embedded broker usecase
> (as noted by in-file comments)
>
>
> *Copy ActiveMQ libs to Glassfish*
>
> Next, copy the following libraries:
>
> log4j-1.2.14.jar
> slf4j-api-1.5.11.jar
> slf4j-log4j12-1.5.11.jar
>
> from the activemq distro/libs directory to the
> <glassfishInstall>/<domain>/lib directory
>
> Deploy the activemq-rar-5.5.1.rar via the Glassfih admin console
> (Application > Deploy)
>
>
> *Configure Glassfish resource adapter & connection resources*
>
> I used the admin console to:
>
> 1) Create a new resource adapter via Resource Adapter Configs menu
>
> 2) Create a new ConnectionPool for the activemq-rar-5.5.1 resource adapter
>
> 3) Create a new Connector resource from the activemq ConnectionPool (e.g.
> jms/activemq/connector for jndi name)
>
> 4) Create a new admin object, corresponding to the jms destination on the
> remote activemq broker (in our case jms/activemq/topic).  Make sure you
> select the activemq resource adapter from the drop down list, and set a
> physical name.
>
>
> *Build an MDB project*
>
> I used Netbeans (7.0.1) to create a new EAR application, and within it a EJB
> module.
>
> Within the EJB module, I created a new MDB, within a mq.beans package.  The
> MDB code simply writes out the content of a textmessage to the standard
> output (the Glassfish server log).  See code below.
>
> Note the annotations, which provide clientId and subsriptionName values
> which correspond to the durable subscriber details we created in ActiveMQ,
> and that the mdb is mapped to the Glassfish admin object jms/activemq/topic,
> which is mapped to the activeMq topic by the jndi name.
>
> Source code for simple MDB:
>
> ****MqTopicMdb.java***
>
> package mq.beans;
>
> import java.io.File;
> import java.io.FileWriter;
> import java.io.IOException;
> import javax.ejb.ActivationConfigProperty;
> import javax.ejb.MessageDriven;
> import javax.jms.JMSException;
> import javax.jms.Message;
> import javax.jms.MessageListener;
> import javax.jms.TextMessage;
>
> /**
>  *
>  * @author Ant
>  */
> @MessageDriven(mappedName = "jms/activemq/topic", activationConfig = {
>    @ActivationConfigProperty(propertyName = "acknowledgeMode",
> propertyValue = "Auto-acknowledge"),
>    @ActivationConfigProperty(propertyName = "destinationType",
> propertyValue = "javax.jms.Topic"),
>    @ActivationConfigProperty(propertyName = "subscriptionDurability",
> propertyValue = "Durable"),
>    @ActivationConfigProperty(propertyName = "clientId", propertyValue =
> "clientID"),
>    @ActivationConfigProperty(propertyName = "subscriptionName",
> propertyValue = "subscriberID")
> })
> public class MqTopicMdb implements MessageListener {
>
>    public MqTopicMdb() {
>    }
>
>    private int count = 0;
>
>    @Override
>    public void onMessage(Message message) {
>        try {
>            count = count + 1;
>            File msgFile = new File("C:\\someUser\\Desktop\\activeMQ
> msgs\\activeMqMessage" + count + ".txt");
>            FileWriter writer = new FileWriter(msgFile);
>            // get a textMessage
>            if (message instanceof TextMessage) {
>                TextMessage txtMsg = (TextMessage) message;
>                System.out.println("Received text message " + count + " from
> activeMQ:\n" + txtMsg.getText());
>                writer.write("Message " + count + ":\n" + txtMsg.getText());
>                writer.close();
>            } else {
>                System.out.println("Received a message, it just isnt a
> textMessage!");
>                writer.write("Message " + count +" received at " +
> String.valueOf(System.currentTimeMillis()));
>                writer.close();
>            }
>        } catch (IOException ioe) {
>            System.out.println("There was an error creating and writing to
> the file. Try a different filepath.\n" + ioe.getCause());
>        } catch (JMSException jmse) {
>            System.out.println("There was a error with the JMS");
>            jmse.printStackTrace();
>        } catch (Exception e) {
>            e.printStackTrace();
>        }
>    }
> }
>
>
> *Create deployment descriptors for MDB*
>
> This was the missing step in my previous efforts - creating appropriate
> deployment descriptor resources for the application - ejb.jar.xml and
> glassfish-ejb-jar.xml - is essential.
>
> ****ejb-jar.xml****
>
> <?xml version="1.0" encoding="UTF-8"?>
>
> <ejb-jar xmlns = "http://java.sun.com/xml/ns/javaee"
>         version = "3.1"
>         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_1.xsd">
> <enterprise-beans>
>    <message-driven>
>           <ejb-name>MqTopicMdb</ejb-name>
>           <ejb-class>mq.beans.MqTopicMdb</ejb-class>
>    </message-driven>
> </enterprise-beans>
> <assembly-descriptor>
>       <container-transaction>
>        <method>
>            <ejb-name>MqTopicMdb</ejb-name>
>            <method-name>onMessage</method-name>
>                <method-params>
>                    <method-param>javax.jms.Message</method-param>
>                </method-params>
>        </method>
>       <trans-attribute>Required</trans-attribute>
>       </container-transaction>
> </assembly-descriptor>
> </ejb-jar>
>
> *****glassfish-ejb-jar.xml*****
>
> <?xml version="1.0" encoding="UTF-8"?>
> <!DOCTYPE glassfish-ejb-jar PUBLIC &quot;-//GlassFish.org//DTD GlassFish
> Application Server 3.1 EJB 3.1//EN&quot;
> &quot;http://glassfish.org/dtds/glassfish-ejb-jar_3_1-
> 1.dtd&quot;>
> <glassfish-ejb-jar>
>  <enterprise-beans>
>    <ejb>
>      <ejb-name>MqTopicMdb</ejb-name>
>      <mdb-resource-adapter>
>      <resource-adapter-mid>activemq-rar-5.5.1</resource-adapter-mid>
>
>      <activation-config>
>      <activation-config-property>
>
> <activation-config-property-name>destination</activation-config-property-name>
>
> <activation-config-property-value>jms/activemq/topic</activation-config-property-value>
>      </activation-config-property>
>
>       <activation-config-property>
>
> <activation-config-property-name>destinationType</activation-config-property-name>
>
> <activation-config-property-value>javax.jms.Topic</activation-config-property-value>
>       </activation-config-property>
>       </activation-config>
>      </mdb-resource-adapter>
>    </ejb>
>  </enterprise-beans>
> </glassfish-ejb-jar>
>
>
> *Deploy the application to the glassfish server, and inspect the server
> log.*  You should see output similar to:
>
> INFO: 2012-01-23 23:38:31,519 [ad-pool-4848(3)] INFO  ActiveMQEndpointWorker
> - Starting
> INFO: 2012-01-23 23:38:31,539 [d-pool-1; w: 20] INFO  ActiveMQEndpointWorker
> - Establishing connection to broker [tcp://2.2.2.2:61616]
> INFO: 2012-01-23 23:38:31,666 [d-pool-1; w: 20] INFO  ActiveMQEndpointWorker
> - Successfully established connection to broker [tcp://2.2.2.2:61616]
> INFO: ActiveMqMdb_app was successfully deployed in 652 milliseconds.
>
>
> *Create a simple producer*
>
> For testing purposes, I also wrote a simple client producer which sends a
> TextMessage to the jms/activemq/topic destination every 3 seconds:
>
> *****JMSClientProducer.java*****
>
> package jmsclientproducer;
>
> import java.text.DateFormat;
> import java.text.SimpleDateFormat;
> import java.util.Calendar;
> import java.util.Date;
> import java.util.GregorianCalendar;
> import java.util.HashMap;
> import javax.jms.Connection;
> import javax.jms.Destination;
> import javax.jms.MessageProducer;
> import javax.jms.Session;
> import javax.jms.TextMessage;
> import org.apache.activemq.ActiveMQConnectionFactory;
>
> /**
>  *
>  * @author Ant
>  */
> public class JMSClientProducer {
>
>    public static void main(String[] args) {
>        try {
>            HashMap<String, String> props = new HashMap<String, String>();
>             ActiveMQConnectionFactory connectionFactory = new
> ActiveMQConnectionFactory("tcp://2.2.2.2:61616");
>
>             Connection connection = connectionFactory.createConnection();
>
>             Session session = connection.createSession(false,
> Session.AUTO_ACKNOWLEDGE);
>
>             Destination destination =
> session.createTopic("jms/activemq/topic");
>
>             MessageProducer producer = session.createProducer(destination);
>
>             connection.start();
>             TextMessage txtMsg;
>             for (int a = 1; a <= 200; a++) {
>                Thread.sleep(2000);
>
>                txtMsg = session.createTextMessage();
>                System.out.println("Sending message " + a + " ...");
>                Date now = new Date(System.currentTimeMillis());
>                DateFormat format = DateFormat.getDateTimeInstance();
>                String nowString = format.format(now);
>
>                txtMsg.setText("***TextMessage:: " + a + "\ndateTime = " +
> nowString + "\nMilliseconds = " + System.currentTimeMillis() + "\n This is a
> test message, set from a standalone client to the ActiveMQ broker,
> jms/activeMq/testTopic destination\n***");
>                producer.send(txtMsg);
>                System.out.println("Completed send for  message " + a + "
> ...\n");
>
>             }
>
>             connection.stop();
>
>             System.exit(1);
>
>        } catch (Exception e) {
>            e.printStackTrace();
>            System.exit(1);
>        }
>    }
> }
>
> The activemq-all-5.5.1.jar, activemq-core-5.5.1.jar, slf4j-api.jar,
> slf4j-log4j-1.2.14.jar and log4j-1.2.14.jar libraries from the activemq/lib
> directory were added to the client project build path.
>
>
> Cheers,
>
> Ant
>
> --
> View this message in context: http://activemq.2283324.n4.nabble.com/Consume-Topic-messages-from-remote-MDB-ActiveMQ-5-5-1-Glassfish-3-1-1-tp4319980p4323048.html
> Sent from the ActiveMQ - User mailing list archive at Nabble.com.



--
http://fusesource.com
http://blog.garytully.com
Reply | Threaded
Open this post in threaded view
|

Re: Consume Topic messages from remote MDB - ActiveMQ 5.5.1 & Glassfish 3.1.1

guerra
In reply to this post by amb_enthusiast
Hi,

It's not necessary to modify the ra.xml in order to setup your own broker configuration. Those properties can be set up from the section "Resource Adapter Configs" on the Glassfish web console.

1. Create a new Resource Adapter config for your new RA.
2. Select the deployed ActiveMQ RA and a Glassfish thread pool.
3. Fill up the properties you need. They show up once you select the deployed RA.

This may help you!
Cheers
Reply | Threaded
Open this post in threaded view
|

Re: Consume Topic messages from remote MDB - ActiveMQ 5.5.1 & Glassfish 3.1.1

garyli_95123
In reply to this post by amb_enthusiast
Hi,

This is really helpful.  Thanks.

Have you try not including destination topic in glassfish-ejb-jar.xml (<activation-config-property-name>destination </...>   "?  If this is not possible, is there another way of not having the topic in this file.  I want to different topic's for different environments (QA/production).  So I don't want the topic hard coded in the file.

Thanks in advance.
Gary