How to monitor ActiveMQ networks

If you’re running ActiveMQ in a distributed setup using network of brokers, you’re probably interested in techniques available to monitor your network. This usually implies viewing the status of the network bridges and generating events when the status changes. There were some improvements in this area for the next 5.5 release and here I’ll try to explain this topic a bit more.

To demonstrate these techniques we need a simple network, so take a look at the one shown in the following diagram.

Network

We see that broker 1 have two network bridges:

  • One created by duplex connection, originating from broker 2
  • and one direct to the broker 3

Now let’s see for starters what JConsole will show us.

JConsole1

JConsole2.png

As you can see, both bridges are shown in JConsole under the Network Bridge tab. You can spot bridges created by remote duplex connectors, by having a connector name pattern like duplex#x and also CreatedByDuplex attribute set to true.

The similar information you can get now in Web Console. There’s a new tab, called Network, which will give you the following view.

Web Console

You can notice that again, you can easily separate bridges created by connectors on this broker and those created by remote duplex connector.

Tools are nice for most usages, but what if you want to monitor your network bridges programatically? Well the first thing you can do is to use JMX API to query bridges. The following application, connects to the broker and lists all of its network bridges.

public class Bridges {
    public static void main(String[] args) throws Exception {
        JMXServiceURL url = new JMXServiceURL(
                "service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
        JMXConnector connector = JMXConnectorFactory.connect(url, null);
        connector.connect();
        MBeanServerConnection connection = connector.getMBeanServerConnection();
        ObjectName name = new ObjectName(
                "org.apache.activemq:BrokerName=static-broker1,Type=NetworkBridge,*");
        Set bridges = connection.queryNames(name, null);
        for (ObjectName bridgeName : bridges) {
            NetworkBridgeViewMBean view =
                    (NetworkBridgeViewMBean) MBeanServerInvocationHandler.newProxyInstance(
                            connection, bridgeName, NetworkBridgeViewMBean.class, true);
            System.out.println("Bridge to " + view.getRemoteBrokerName()
                    + " (" + view.getRemoteAddress() + ") "
                    + ((view.isCreatedByDuplex() ? "- created by duplex" : "")));
        }
    }
}

So if you run it against broker 1, you’ll get something like

Bridge to static-broker3 (localhost/127.0.0.1:61617) Bridge to static-broker2 (/127.0.0.1:52776) - created by duplex

You can see both bridges, and an indication that bridge to broker 2 is created by remote duplex.

JMX API will give you just the static snapshot of the available bridges. If you’re interested in notifications when bridges are being stopped or started, you can use advisory messages. The following example shows how to subscribe to the appropriate advisory topic and get events of the interest.

public class BridgeAdvisories implements MessageListener { 
 public static void main(String[] args) throws Exception { 
   ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616"); 
   Connection conn = factory.createConnection(); Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);     
   MessageConsumer consumer = sess.createConsumer(AdvisorySupport.getNetworkBridgeAdvisoryTopic());
   consumer.setMessageListener(new BridgeAdvisories()); conn.start(); 
 } 

  @Override 
  public void onMessage(Message message) { 
    try { 
      BrokerInfo brokerInfo = (BrokerInfo) ((ActiveMQMessage) message).getDataStructure();
      boolean started = message.getBooleanProperty("started");
      if (started) { 
        boolean createdByDuplex = message.getBooleanProperty("createdByDuplex");
        System.out.println("Network bridge to " + brokerInfo.getBrokerName() + " (" 
      + brokerInfo.getBrokerURL() + ") has been started " + (createdByDuplex ? "by duplex" : ""));
      } else { 
        System.out.println("Network bridge to " + brokerInfo.getBrokerName() + " (" 
      + brokerInfo.getBrokerURL() + ") has been stopped"); 
      }
    } catch (JMSException e) { e.printStackTrace(); } 
  } 
}

If you run this against our broker 1 and start and stop brokers 2 and 3, you can expect the output similar to the following.

Network bridge to static-broker3 (tcp://dejan-bosanacs-macbook-pro.local:61617) has been stopped 
Network bridge to static-broker3 (tcp://dejan-bosanacs-macbook-pro.local:61617) has been started 
Network bridge to static-broker2 (tcp://dejan-bosanacs-macbook-pro.local:61618) has been stopped 
Network bridge to static-broker2 (tcp://dejan-bosanacs-macbook-pro.local:61618) has been started by duplex

So with this we covered techniques that you can use to monitor networks of ActiveMQ broker, which I hope you’ll find useful. If you’re interested in learning more about ActiveMQ (and related technologies), you can attend one of the online trainings organized by FuseSource

ActiveMQ in Action in Production

coverIt’s always a good feeling when the book project goes into the production, and that’s what happened to ActiveMQ in Action this week.

If you already bought MEAP access plus printed version of the book, you can expect your printed version in the next few months. If not, it’s still not too late as we’re offering 40% discount to celebrate going into the production. Just use activemq40 coupon code at the time of checkout.

Enjoy reading!

ActiveMQ 5.4.1: Encrypted passwords

While configuring ActiveMQ for a production use, you usually need to store passwords in your configuration files. Passwords are usually needed for:

  • Simple authentication plugin
  • JDBC/LDAP passwords
  • Accessing secured brokers by Web Console, Camel, etc

Naturally, people don’t want to keep plain passwords in the configuration files. ActiveMQ 5.4.1 comes with a solution for that. Thanks to the
integration with Jasypt library, your passwords can be now stored encrypted.

For a full description of this new feature see http://activemq.apache.org/encrypted-passwords.html.

Here, I’ll briefly describe how to use it and what implications does it have for your deployment. First of all, for your convenience we provided new commands that you can use to encrypt/decrypt passwords from the command line.

Encrypted passwords should replace plain ones in the properties files and with just a little XML config (replacing standard property configurer with one provided by Jasypt) you should be ready to go.

But there’s one tricky part to all this. You need to provide secret to the encryptor somehow. The most secure way to do this is by using the environment variable. You should set the it before you start the broker and unset it just after.

Of course, there are other methods you can use to achieve this. But the only one currently provided by Jasypt assumes that you need to put that password in your xml configuration file. It’s needless to say that compromising the security of this password affects all other encrypted passwords. There’s always a room for improvement, so probably we can make it easier for you to enter this password while starting the broker in the future.

If you want (need) extra security, there’s usually a price to be payed in complexity of your deployment procedures. Setting/unsetting environment variables every time you start the broker (for now) is a small one if you want your passwords to be safe.

By the way don’t forget to attend Apache Camel webinars organized by FuseSource in September.

What’s new in Apache ActiveMQ 5.4.0

Apache ActiveMQ 5.4.0 is out. Beside our usual dedication to making it bullet-proof by adding a lot of test cases and resolving issues reported by our vibrant community, this release contains a lot of new features (some of which has already been covered here). In this post I’ll try to sum up the new features that we included in this release. As the development pace was very rapid, some of them haven’t been documented yet, but that’ll change soon too. So let’s start:

These are definitely interesting times for open source messaging and be sure to expect a lot more from ActiveMQ team (such as new Apollo architecture). Also, don’t miss Rob Davies talking on Deploying ActiveMQ in the Enterprise on August 19th.

Fast producer failover with ActiveMQ

When you’re sending messages to a cluster of ActiveMQ brokers using failover protocol and the current broker dies, the transport will try to connect and send messages to the next one. If that one is unavailable it will try next and so on and so on. So what happens when all brokers in the cluster are down? You’ll get the feeling that send call is hanging. At least until one of the brokers gets up again.

For some applications this is a desired behavior, but others don’t want (or can’t afford) to hang on sending messages under any circumstances. The easy solution for this is to use the timeout option on a failover transport. Take a look at the following queue producer.

public class QueueProducer {
  public static void main(String[] args) throws Exception {
        ActiveMQConnectionFactory factory =
          new ActiveMQConnectionFactory("failover:(tcp://localhost:61616)?timeout=1000");
        Connection connection = factory.createConnection();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        connection.start();
        Queue queue = session.createQueue("TEST");
        MessageProducer producer = session.createProducer(queue);
        // send messages
        for (int i = 0; i < 1000; i++) {
                producer.send(session.createTextMessage(i + " message"));
                System.out.println("Sent message " + i);
                Thread.sleep(1000);
        }
        producer.close(); session.close(); connection.close();
  }
}

What we have here is a producer that tries to send 1000 messages to the broker listening at port 61616. If that broker is down, it will wait one second (timeout=1000) before it fails. So when the broker is down, you can expect something like this:

2010-08-16 15:52:12,336 [main           ] INFO  FailoverTransport           - Failover timed out after 1008ms
Exception in thread "main" javax.jms.JMSException: Failover timeout of 1000 ms reached.
	at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:62)
	at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1298)
	at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(ActiveMQConnection.java:1382)
	at org.apache.activemq.ActiveMQConnection.createSession(ActiveMQConnection.java:309)
	at icap.QueueProducer.main(QueueProducer.java:15)
Caused by: java.io.IOException: Failover timeout of 1000 ms reached.
	at org.apache.activemq.transport.failover.FailoverTransport.oneway(FailoverTransport.java:529)
	at org.apache.activemq.transport.MutexTransport.oneway(MutexTransport.java:40)
	at org.apache.activemq.transport.ResponseCorrelator.asyncRequest(ResponseCorrelator.java:81)
	at org.apache.activemq.transport.ResponseCorrelator.request(ResponseCorrelator.java:86)
	at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1276)
	... 3 more

So how does it work under the hood? The failover transport will try to reconnect to the broker (with interval of 100 ms between retries) and if don't succeed in a specify amount of time it will throw an exception. What implication does this introduce? The obvious one is that you cannot specify "small" timeout periods (less than 100 ms) as you'll lose your failover functionality. Again, for most applications this is more than enough, but even for those that require "fast producer failure" there is a solution. Actually two of them.

Solution number one is to use TransportListener to be notified on your connection status. So when you know you have a valid connection, you send your messages in a regular manner. And execute your backup logic in case all brokers are down. Consider the following:

public class FastFailProducer implements TransportListener {
  boolean volatile connected = false;
  public void run() throws Exception {
        ActiveMQConnectionFactory factory =
          new ActiveMQConnectionFactory("failover:(tcp://localhost:61616)?timeout=1000");
        factory.setTransportListener(this);
        Connection connection = factory.createConnection();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        connection.start();
        Queue queue = session.createQueue("TEST");
        MessageProducer producer = session.createProducer(queue);
        // send messages
        for (int i = 0; i < 1000; i++) {
             if (connected) {
                // send a message
                producer.send(session.createTextMessage(i + " message"));
                System.out.println("Sent message " + i);
             } else {
                // execute your backup logic
                System.out.println("Message " + i + " not sent");
             }
             Thread.sleep(1000);
        }
        producer.close(); session.close(); connection.close();
  }
  public static void main(String[] args) throws Exception {
     FastFailProducer producer = new FastFailProducer();
     producer.run();
  }
  public void transportResumed() {
     connected = true;
  }
  public void transportInterupted() {
     connected = false;
  }
  public void onException(IOException error) {
    connected = false;
  }
  public void onCommand(Object command) {}
}

Here we modified a previous example, so that now we implement the transport listener. When the link goes up, transportResumed() gets called. When the link goes down, transportInterupted() gets called. When there's an unrecoverable transport exception (like timeout, or maximum number of retries are reached) onException() gets called.

So now we can have a state of our connection and decide whether we want to send a message or just fail back even before we try. Executing the example against the broker that goes up and down, you can expect the following result

2010-08-16 17:09:23,799 [ActiveMQ Task  ] INFO  FailoverTransport   -
  Successfully connected to tcp://localhost:61616
Sent message 0
Sent message 1
Sent message 2
Sent message 3
2010-08-16 17:09:27,843 [127.0.0.1:61616] WARN  FailoverTransport      -
Transport (localhost/127.0.0.1:61616) failed to tcp://localhost:61616 ,
  attempting to automatically reconnect due to: java.io.EOFException
Message 4 not sent
Message 5 not sent
Message 6 not sent
Message 7 not sent
Message 8 not sent
Message 9 not sent
2010-08-16 17:09:33,164 [ActiveMQ Task  ] INFO  FailoverTransport  -
  Successfully reconnected to tcp://localhost:61616
Sent message 10
Sent message 11
Sent message 12
Sent message 13

Now this is all fine and well, but in most cases when your connection is down you simply want to queue messages somewhere else until remote broker comes up. Why don't you just use embedded broker for that? So with this second approach, you actually always send messages to the broker embedded in your producer application. That broker is then connected to the remote broker using the failover protocol. In this way your producers can work without caring about the state of the connection. So let's change the original example to make it work with the embedded broker:

public class EmbeddedProducer {
  public static void main(String[] args) throws Exception {
        ActiveMQConnectionFactory factory =
          new ActiveMQConnectionFactory("vm:(broker:(network:static:tcp://localhost:61616)?persistent=false&useJmx=false)");
        Connection connection = factory.createConnection();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        connection.start();
        Queue queue = session.createQueue("TEST");
        MessageProducer producer = session.createProducer(queue);
        // send messages
        for (int i = 0; i < 1000; i++) {
                producer.send(session.createTextMessage(i + " message"));
                System.out.println("Sent message " + i);
                Thread.sleep(1000);
        }
        producer.close(); session.close(); connection.close();
  }
}

Basically we only changed the connection url. So now we send messages to the in-memory only embedded broker, connected to the remote broker. Of course, this is just an example, you can configure you embedded broker anyway you like. One thing that is important is that with the configuration like we have in this example, we must have a consumer on a remote broker in order to have messages forwarded there. This is configurable and you can have all your messages forwarded to the remote broker using staticallyIncludedDestinations.

To run a consumer, we can use ActiveMQ consumer tool and run something like

/activemq/example$ ant -Dsubject=TEST -Durl="failover:(tcp://localhost:61616)" consumer

Now you can run the producer, stop and start the broker and see that messages are flowing through the system and that producers are not affected by the state of the remote broker.

So there you go, I hope I managed to explain how failover protocol affects producers and how you can find an ideal setup for your application. By the way, if you're in Boston area be sure you pop by to FUSE meetup on August 17th.
heather like viagra; Cheap Generic Viagra viagra and pulmonary fibrosis
viagra enhancement Cheapest Viagra Prices health net hmo ca viagra
viagra test; Lowest Price Viagra discount viagra sale
"viagra sale prices" Viagra No Prescription viagra moa
viagra dosages Viagra Soft Tabs viagra ibuprofen
viagra and sexual misfunction Buying Viagra find search viagra free?
availability of viagra in new zealand Viagra Alternative viagra patent expires
holdere a href womens viagra a Viagra Prescription online viagra pharmacy
effects viagra 200mg Viagra Professional viagra smaple

ActiveMQ 5.4: Seamless OSGi Integration

For upcoming ActiveMQ 5.4.0 release we did a lot of work to make it a better citizen in OSGi land. Let’s walk through some of the stuff you can do now. First of all download and install recently released Apache Karaf 2.0.0.

Now if you want to play with all these stuff before the ActiveMQ 5.4.0 is officially released, you need to edit

${KARAF_HOME}/etc/org.ops4j.pax.url.mvn.cfg

and add

https://repository.apache.org/content/repositories/snapshots/

to the list of available repositories.

Once in the Felix runtime, you can now install all these new “features” by doing something like

karaf@root> features:addUrl mvn:org.apache.activemq/activemq-karaf/5.4-SNAPSHOT/xml/features

Of course, when 5.4.0 is released (and for all newer versions), you should only change the appropriate version in the url above.

You want to install the broker? Easy. Just type

karaf@root> features:install activemq-spring

and it’s there. Also, if you prefer to use Blueprint instead of Spring you can do

karaf@root> features:install activemq-blueprint

Once installed, the broker can be started with

karaf@root> activemq:create-broker

(add --type blueprint if you wish to use blueprint configuration).

Of course, no ActiveMQ installation is complete without Web Console. To monitor our installed broker, we should take the following steps:

  • Install war feature
    karaf@root> features:install war
  • Configure system properties, by adding the following snippet
    webconsole.type=properties
    webconsole.jms.url=tcp://localhost:61616
    webconsole.jmx.url=service:jmx:rmi:///jndi/rmi://localhost:1099/karaf-root
    webconsole.jmx.user=karaf
    webconsole.jmx.password=karaf
    

    to etc/system.properties

  • Install and run the web console
    karaf@root> features:install activemq-web-console 

    .

  • Visit the console at http://localhost:8181/activemqweb/ and enjoy.

You can find more detailed information on the topic reading the following article.

Also, if you haven’t already, check the free chapters of ActiveMQ and Camel in Action series books available at FUSESource

Securing ActiveMQ 5.3.1 console

In many environments, users want to restrict access to ActiveMQ web server (Jetty) and web console application in particular. Here’s how to do it for ActiveMQ 5.3.1 version of broker.

In 5.3.1, the whole web server configuration is placed in the ${ACTIVEMQ_HOME}/conf/jetty.xml file. The configuration file you can find at here is a drop-in replacement for a default jetty configuration and you should place it in your configuration folder.

Besides that you’ll need to create a ${ACTIVEMQ_HOME}/conf/jetty-realm.properties with the following content:

It’s a classic Jetty hash user realm file that defines one user, with it’s password and roles in each line (Downloadable from here). By default, as you can see in the realm file, you can use admin/admin credentials to access ActiveMQ web server. You should adapt this file to your security needs.

So, after making these changes and restarting your broker, you should get basic authentication dialog before you’d be able to proceed. If you want to later on disable the authentication, you can do that easily by changing the line

to

ActiveMQ 5.4.0 will come with this configuration enabled by default and if you wish to secure older versions of the ActiveMQ take a look at this article.

ActiveMQ 5.3.1 Released

Apache ActiveMQ 5.3.1 has just been released. It’s primarily the maintenance release, including nearly 100 bug fixes and improvements over the previous 5.3.0 version. The full list of improvements and bug fixes, as well as the download link, can be found at the release page.

  • JDBC message store – a big effort has been made to make JDBC store as reliable as other file-based stores for use in complex high-load use cases.
  • nio and stomp+nio transports – initial implementation of stomp+nio transport, introduced in 5.3.0 version contained some resource leaks, but also revealed some problems with the nio transport. All these are now fixed, thoroughly tested and ready for production use
  • OSGi integration – a lot of small improvements in this area should provide much better integration of the broker in OSGi environments. Especially, we provided resources for seamless deployment in Apache Karaf OSGi runtime. This will be the topic of the following blog post (so stay tuned!)
  • Web console security – Web console is now secured against XSS and XSRF attacks, so it’s safe to be deployed publicly (of course with proper authentication set in place)

Enjoy this release, while we work on delivering 5.4.0 in coming months (or even weeks) with more bug fixes and features, such as scheduled messages and web socket support

ActiveMQ 5.4: Stomp over Web Sockets

Exchanging messages with the broker directly from the web browser was always interesting use case (and used by many developers). That’s why ActiveMQ was supporting Ajax API for the long time. It uses Jetty Continuations to implement threadless waiting and asynchronous delivery of messages to the web page.

HTML 5 introduced web sockets, as a standardized way to communicate asynchronously with the server from a web page. This is practically an ideal channel for implementing asynchronous messaging for web pages, so it’s no surprise we had it on a todo list for a long time. Also, since JavaScript easily handles text and JSON formatted data, Stomp protocol is a natural choice for the wire protocol to be used over web sockets.

This solution should bring better messaging capabilities to JavaScript clients then simple Ajax API, as implementing Stomp in JavaScript brings much more messaging-oriented API and features such as transactions, for example.

Jeff Mesnil, of JBoss, implemented a nice JavaScript library for doing Stomp over Web Sockets. So it was time to get this off todo list and implement Web Socket support for ActiveMQ. So, in the latest ActiveMQ 5.4 snapshot, you can find new ws (WebSocket) protocol that allows you to exchange message with the broker, using JavaScript client from your browser.

In the rest of this post, I’ll walk you through the steps needed to configure this transport in the broker and run chat example that comes with the Jeff’s library.

There’s nothing spectacular you need to do on the broker side to enable this support:

  • Download the latest ActiveMQ 5.4 snapshot and install it properly.
  • Edit ${ACTIVEMQ_HOME}/conf/activemq.xml file and add ws transport, like this
    
        <transportConnectors>
            <transportConnector name="openwire" uri="tcp://0.0.0.0:61616"/>
            <transportConnector name="websocket" uri="ws://0.0.0.0:61614"/>
        </transportConnectors>
    
  • Get the client library
    git clone git://github.com/jmesnil/stomp-websocket.git

    and copy it to the ${ACTIVEMQ_HOME}/webapps/demo/ folder

  • Start ActiveMQ
    ${ACTIVEMQ_HOME}/bin/activemq
  • Now you can see chat example in the demo application

    http://localhost:8161/demo/stomp-websocket/example/chat

  • Enjoy playing with your new toy :)

One thing worth noting is that web sockets (just as Ajax) implements same origin policy, so you can access only brokers running on the same host as the web application running the client.

Of course, this is an initial implementation of this functionality so your feedback is more then welcome. Before ActiveMQ 5.4 is released, we’ll polish it further and integrate client and example in the ActiveMQ web demo application.