Posting messages from a standalone client

The necessary code to write messages to a WebLogic Server queue doesn't have to use any WebLogic specific classes, just plain regular javax.jms.* and javax.naming.* components.

There are some classes and interfaces provided by WebLogic that help us access WebLogic-specific features, but as they address very specialized scenarios, chances are you're not going to use them very often. They are inside the weblogic.jms.extensions package, and you can find their Javadoc at http://docs.oracle.com/middleware/1212/wls/WLAPI/weblogic/jms/extensions/package-summary.html.

As said earlier in this chapter, the business functionality we're going to implement will act as a bridge between the partner's system and the Theater module deployed at their installations, and will receive information about new exhibition dates that must be uploaded to our module.

To accomplish this, we will create a standalone Java project named RemoteClient and add a Java class that will read the command-line arguments that represent the new exhibition, pack them inside an Exhibition class instance, and post it to a message queue.

Creating the project

The following are the steps to set up the environment that our code needs:

  1. Open Eclipse IDE, select menu entries File, New…, and Project…. Then, type Java in the Wizards text field, click on the Java Project entry, and then on the Next button.
  2. Type RemoteClient as Project Name, make sure you're using JDK 1.7 in the JRE group (change it if necessary), and click on Next.
  3. Click on the Libraries tab and then on the Add External JARs… button.
  4. Navigate to /$MW_HOME/wlserver/server/lib and select the wlthint3client.jar file.
  5. As we're going to instantiate the Exhibition class, we also need to add a reference to its package, TheaterBO.jar, in the same way. Click on the Add External JARs… button, then navigate to the location where you saved the TheaterBO.jar file that is deployed as a shared library.

    Tip

    If you don't remember where the deployed TheatherBO.jar file is, open WebLogic's administration console, go to the Deployments page, and click on the theaterBO(1.0,1.0.0) entry. The Overview tab will be loaded, and the Path line will tell you where to find it.

  6. Click on Finish. You may choose to open the Java perspective.

Coding the message producer

As there are no specific needs regarding the message producer, we will write the code inside the main method of our class.

  1. Create a package named com.packt.client inside the RemoteClient project, and add a class named Enqueue inside this package.
  2. We will declare the address and component names as static constants inside the class as follows:
    static final String WLS_ADDRESS = 
                    "t3://localhost:7001";
    static final String WLS_CTX_FACTORY = 
                    "weblogic.jndi.WLInitialContextFactory";
    static final String JMS_QUEUE_FACTORY = 
                    "weblogic.jms.ConnectionFactory"; 
    static final String JMS_QUEUE_NAME = 
                    "jms.tickets.exhibition";
  3. Create the public main method that is going to hold all the logic; also, it is going to throw the superclass Exception, so we save a few try/catch blocks:
    public static void main(String args[]) throws Exception {
    }
  4. We first need to acquire a remote connection to WebLogic Server. You may need to change the username and password to be able to connect to your server:
    Context ct;
    Hashtable<String, String> env = new Hashtable<>();
    
    env.put(Context.PROVIDER_URL, WLS_ADDRESS);
    env.put(Context.INITIAL_CONTEXT_FACTORY,
                                       WLS_CTX_FACTORY);
    env.put(Context.SECURITY_PRINCIPAL, "weblogic");
    env.put(Context.SECURITY_CREDENTIALS, "welcome1");
    
    // Get a server connection 
    ct = new InitialContext(env);
  5. Now we create and load instances of Movie, Room, and Exhibition using command-line arguments as attribute values:
    /* 
     * Argument sequence and format:
     *   0: Movie Id
     *   1: Room Id
     *   2: Exhibition date - MM.DD.YYYY
     *   3: Exhibition time - HHMM
     */ 
    Movie movie = new Movie();
    movie.setId(Integer.parseInt(args[0]));
    
    Room room = new Room();
    room.setId(Integer.parseInt(args[1]));
    
    Exhibition exhibition = new Exhibition();
    
    exhibition.setMovie(movie);
    exhibition.setRoom(room);
    exhibition.setDate(new SimpleDateFormat("MM.dd.yyyy").
                                  parse(args[2]));
    exhibition.setHour(Integer.parseInt(args[3]));
  6. These are the declarations of all JMS components we will need, all from the package javax.jms:
    QueueConnectionFactory qcf;
    QueueConnection qc = null;
    QueueSession qs = null;
    QueueSender sender = null;
    
    Queue queue;
    ObjectMessage msg;
  7. And here we grab the necessary JMS resources, create a sender, and post the message. This whole block is wrapped inside a try/catch block that's supposed to deal with any problems that may arise. At the end, there's a finally block to close the JMS resources, as they don't support Java 7's try-with-resources feature yet:
    try {
       // Set up JMS components
       qcf = (QueueConnectionFactory) ct.lookup(JMS_QUEUE_FACTORY);  
       qc = qcf.createQueueConnection();
       qs = qc.createQueueSession(false, 
                                  Session.AUTO_ACKNOWLEDGE);
    
       // Get a handle to the JMS queue
       queue = (javax.jms.Queue) ct.lookup(JMS_QUEUE_NAME);
    
       // Create ...
       msg = qs.createObjectMessage();
       msg.setObject(exhibition);
    
       // ... and send the message
       sender = qs.createSender(queue);
       sender.send(msg);
    } catch(Exception e) {
       e.printStackTrace();
    } finally {
       // Doesn't support try-with-resources yet...
       try { sender.close(); } catch (Exception e) { }
       try { qc.close(); } catch (Exception e) { }
       try { qs.close(); } catch (Exception e) { }
       try { ct.close(); } catch (Exception e) { }
    }
  8. Save everything and check and correct any compilation errors.

    Note

    You will see an error mark at the top of the class. If you hover the mouse over it, the message The type javax.persistence.TemporalType cannot be resolved. It is indirectly referenced from required .class files will pop up. This class is used by the TheaterBO package, but as we aren't dealing with the persistence layer here, we can ignore the error. Compilation and execution will run as expected.

The code is ready to generate messages. Let's post a few entries!

Queuing messages

We're going to execute the client from Eclipse, so we need to create a run configuration:

  1. Just run the class for the first time and Eclipse will create a configuration for you: right-click on the class' name, then select Run As and then Java Application. An exception will be displayed, as we don't have any command-line arguments yet—just ignore it.
  2. Right-click on the class name again, and then select Run As and the Run Configurations… option in the context menu.
  3. In the Run Configurations window, find the Java Application entry at the list to the left, and then click on at the subentry with our class' name, Enqueue.
  4. Click on at the Arguments tab, and enter the 5 1 01.01.2013 1400 sequence in the Program arguments box.

    Tip

    The sequence of the parameters represents the movie ID, room ID, and exhibition's date, in the format MM.DD.YYYY and time.

  5. Click on Run. If the execution finishes without errors, your message will most likely be waiting for consumption at the queue.

As we still don't have a consumer attached to the queue, you can check it and see that there are messages waiting for delivery:

  1. Access WebLogic's administration console, and on the navigation tree click on Services, Messaging, and then JMS Modules.
  2. Click on the name of our module, JMSModule-Tickets, and then on the queue's name, ExhibitionQueue.
  3. Click on the Monitoring tab and you can check how many consumers the queue has, the number of current and total messages, along with other data:
    Queuing messages

    Note

    The Messages Pending column shows the messages that cannot be consumed because they are still part of a receive transaction. The Messages Current column shows how many messages are available to the consumers, and Messages Total indicates how many messages have been received by this queue.

  4. You can drill down and see the messages by checking the box next to the name and then clicking on the Show Messages button:
    Queuing messages

Notice the buttons just above the message table. Other than checking the messages already in the queue, you can:

  • Create new messages from the administration console.
  • Delete selected messages or all messages from the queue.
  • Move some or all the messages from this queue to another one.
  • Import and export messages to and from XML files with a specific format. These functionalities don't work with object messages unless the classes inside the payload are available from the server classpath.

As we post object messages, if you click on the message ID, a screen with the warning Unable to view message, reason = java.class.ClassNotFoundException: com.packt.domain.theater.Exhibition shows up. You must add the class' package to WebLogic's classpath, and the easiest way to accomplish this is to drop the TheaterBO.jar file for our example into the /lib folder of the target domain, $ DOMAIN_HOME/tickets, and restart the server.

This is how the detail screen should look like if you do this:

Queuing messages

When you already have a consumer that is attached to a queue and needs to check the messages coming through it, you can stop the queue's consumption. Also, you can pause the production and/or insertion of messages of a given queue, for instance, to avoid an overload situation. Let's define these administration-related terms:

  • Production: This is used for posting messages into the queue. When it's paused, no producer can post messages.
  • Insertion: This does the same as the previous flag, but also blocks messages that are in flight, for instance, messages that are waiting to be inserted in the queue because its quota has been reached, or messages with a delivery time header that hasn't been reached yet.
  • Consumption: The messages are received and put in the queue as usual, but the engine doesn't notify any consumers about them, so there's no message delivery.

Note

These pauses—production, insertion, and consumption—are held until the server goes down. If you restart a WebLogic node, all states are set back to enabled, or more specifically, to the default value for each state, which you can configure in the Configuration tab, the General inner tab, and the Advanced group of a destination component.

Here's the screen where we can pause or resume the production and/or consumption of our queue:

Queuing messages

Now that we confirmed that there's a message or two waiting in the queue, let's code a bean to consume them.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.37.196