Sunday, April 6, 2014

JMX for WAS Admins

Give me six hours to chop down a tree and I will spend the first four sharpening the axe.-Abraham Lincoln

Part I: JMX for Change Management


It is my personal belief that JMX had been a under dog since from it's inception, for some reason it was never adopted by development and administration communities, with exception to some commercial products.Once you see how easy it is to get it working, with it’s limitless capabilities, you will be convinced to make it a default tooling solution for your application management and admin tasks.

 

 What is JMX and Mbeans?

Java Management Extensions is a Java Technology that provides tools for managing interface and performance of Java applications. If you are interested, read up on JMX and MBeans.

Without going into boring details, here are some of the benefits to use JMX
  • Platform neutral for any admin tasks
  • Works great remotely, using SOAP or RMI. Makes it possible to provide a centralized solution
  • All appserver admin tools, WAS consol and wsadmin use JMX internally, so all admin functions are exposed as JMX Mbeans (I like Mbeans, next to my coffee bean :)
  • Rich language Java strengthens the JMX capabiities
  • Relatively easy to use same JMX tool on different appserver products, such as JBOSS, WebLogic and Oracle Appserver (never tried it myself )
  • More so on why you need JMX  from Oracle site: JMX
  • You must have really been bored with Jacl and Jython already

What can you possibly to do with JMX?

        Deployment Utility: I developed a deployment utility a while back, which has been in use since from WebSphere 5,6,7 & V8 now, pretty much with no change except for updating jars. It enabled our QM department to be able to deploy web applications from a centralized server to number of different WebSphere appservers, which are on different platforms, ranging from Windows to ZOS with varying WebSphere versions.

        JMX Agent: Have your insider, agent running in each JVM. You can write a JMX bean that could be part of JVM life cycle, alerting you on all life cycle events. It could even take commands from you and execute on the appserver. One of the major Java exploit was using this JMX feature on client side Java 7, just watch out your implementation.

You can develop a JMX monitor which could poll different appserver for specific events or triggering points for alert.

If you are developing a web application, you can write Mbeans to assist you as an insider, perhaps health checks on your application's vital components. If you ever need to refresh you global static data, you can achieve it by calling your Mbean without having to restart the application.

It is relative easy to build JMX based tool, let us see what it takes to build one. As a first task, let’s connect to an appserver.


        Properties adminProps = new Properties();
        adminProps.setProperty(AdminClient.CONNECTOR_TYPE,  AdminClient.CONNECTOR_TYPE_SOAP);
        adminProps.setProperty(AdminClient.CONNECTOR_HOST,host);
        adminProps.setProperty(AdminClient.CONNECTOR_PORT, port);
    adminProps.setProperty(AdminClient.CONNECTOR_SECURITY_ENABLED, "true");
    adminProps.setProperty(AdminClient.USERNAME, SOAPUser);
     adminProps.setProperty(AdminClient.PASSWORD, SOAPPass);
     adminProps.setProperty("com.ibm.ssl.trustStore", keyLocation+"DummyServerTrustFile.jks");
        adminProps.setProperty("com.ibm.ssl.keyStore", keyLocation+"DummyServerKeyFile.jks");
        adminProps.setProperty("com.ibm.ssl.trustStorePassword", "WebAS");
        adminProps.setProperty("com.ibm.ssl.keyStorePassword", "WebAS");
      adminClient = AdminClientFactory.createAdminClient(adminProps);
        session=adminClient.isAlive();
       System.out.println("isAlive:"+session.toString());


As you noticed, we need few things in order to connect to an appserver, valid credentials and the public certificate from the target appserver (cell cert if it is a clustered environment), since most of the installations use self signed certificate with WAS Admin security enabled. If Admin security is not enabled, you don't need SSL connection. You would have to import the server certificate into DummyServerTrustFile.jks repository.

Now that you got a valid adminClient object, you can invoke command that can perform every task that you do on WAS console. Here is a snippet for stopping an application.

           String[] signature = new String[3];
           String[] params = new String[3];
           params[0]=applicationName;
           params[1]=null;
           params[2]=session.toString();
          signature[0] = "java.lang.String";
          signature[1] = "java.util.Hashtable";
          signature[2] = "java.lang.String";

          Set oSet = adminClient.queryNames(new ObjectName(oNameQuery.toString()), null);
          Iterator i = oSet.iterator ();
          ObjectName srv = null;
          while (i.hasNext()) {
           srv= (ObjectName) i.next();
           adminClient.invoke(srv,"stopApplication",params,signature);

** Keep in mind these commands are asynchronous, in order to know the actual status, you would have to implement a callback listener which would be invoked when Dmgr emits "completion" event.

Instead of "stopApplication", you can replace it with startApplication or exportApplication (needs different parameter). Installing a new application needs few more extra steps, as you would have to map modules to containers. Here is the extract doing exactly that.

   Hashtable props = new Hashtable();
   props.put (AppConstants.APPDEPL_LOCALE, Locale.getDefault());
   Hashtable opts = new Hashtable();
   Hashtable module2server = new Hashtable();
   AppDeploymentTask task =null;
   AppDeploymentController flowController = null;
    flowController =AppDeploymentController.readArchive  (localEAR, props); 
    task =flowController.getFirstTask();
   while (task != null) 
   {
         String[][] data = task.getTaskData();
          if (task.getName().equals("MapModulesToServers" )) 
          {
              for (int i=1; i < data.length; i++)
                   module2server.put ((data[i][1]).replace(',','+'), ("Websphere:cluster="+cluster));
          }
         task =flowController.getNextTask();
    }
   AppManagement appMgmt = AppManagementProxy. getJMXProxyForClient(adminClient);
   opts.put (AppConstants.APPDEPL_MODULE_TO_SERVER, module2server);
   opts.put (AppConstants.APPDEPL_PRECOMPILE_JSP,true);
   opts.put("cell.name",cellName);
   appMgmt.installApplication(installEAR,  opts, null);

Wrapping WAR into EAR

I personally don't like applications coming in War format, as it leaves room for admins to set wrong context root, but as many of you have seen, most vendor products come in not so handy War file format.This is where JMX can help you, you can create the Ear file by wrapping on vendor War module like below.

   opts.put (AppConstants.APPDEPL_LOCALE, Locale.getDefault());
   opts.put(AppConstants.APPDEPL_WEBMODULE_CONTEXTROOT, appContextRoot);
   opts.put(AppConstants.APPDEPL_APPNAME, actualName);
   opts.put(AppConstants.APPDEPL_MODULETYPE_WEB,actualName);
   opts.put(AppConstants.APPDEPL_MODULE, warModuleName);
   opts.put(AppConstants.APPDEPL_WEB_MODULE, warModuleName);
 
   AppManagementHelper.wrapModule(warLocation, earOutputLocation, warModuleName, opts);


If you are planning to use JMX targeting to manage many different applications, it would be a good idea to keep them in a property file so that the utility can pick up appropriate values for each application. In my next blog, let's explore on how JMX could be used as an insider agent for your JVMs or applications.

No comments:

Post a Comment