19.9. WS-CM Management Clients

19.9.1. WS-CM Clients Overview

This chapter discusses the implementation of JMX management clients for managed web services. It focuses on RMI as the JMX transport protocol because RMI is ubiquitously supported by the Java SDKs. But it is possible to plug in any JMX transport protocols and the configuration settings listed in section WS-CM Configuration allow to configure the server side extensively.

19.9.2. Unsecured RMI Client

This client requires that an RMI registry is running that holds the RMI stub object. This is the default setting for a managed Metro web service and will work out of the box with GlassFish.

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import javax.management.Attribute;
import javax.management.MBeanServerConnection;
import javax.management.JMException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class Client {

public static void main(String[] args)
  throws MalformedURLException, IOException, JMException {
    final String serviceId = "service-1";
    // Force the service to deploy
    final URL initUrl = new URL("http://localhost:8080/webapp/port" + "?init-wscm");
    final URLConnection initConnection = initUrl.openConnection();
    Thread.sleep(5000L);
    // The RMI registry is running on the local host in this case.
    JMXServiceURL url = new JMXServiceURL(
      "service:jmx:rmi:///jndi/rmi://localhost:8686/metro/" + serviceId);
    JMXConnector connector = JMXConnectorFactory.connect(url);
    MBeanServerConnection connection = connector.getMBeanServerConnection();
    connection.setAttribute(
      new ObjectName("com.sun.xml.ws.config.management:className=" + serviceId),
      new Attribute("policies", "<sunman:Policies>...</sunman:Policies>"));
    connector.close();
    }
}

19.9.3. JMX Helper Methods

The package com.sun.xml.ws.api.config.management.jmx contains some helper code with the names of the commonly used JMX attributes. The client from the previous section would look like this:

import com.sun.xml.ws.api.config.management.jmx.JmxConstants;
import com.sun.xml.ws.api.config.management.jmx.JmxUtil;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.management.Attribute;
import javax.management.MBeanServerConnection;
import javax.management.JMException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class Client {

public static void main(String[] args)
  throws MalformedURLException, IOException, JMException {
    final String serviceId = "service-1";
    // The RMI registry is running on the local host in this case.
    JMXServiceURL url = new JMXServiceURL(
      JmxConstants.JMX_SERVICE_URL_DEFAULT_PREFIX + serviceId);
    JMXConnector connector = JMXConnectorFactory.connect(url);
    MBeanServerConnection connection = connector.getMBeanServerConnection();
    connection.setAttribute(
      JmxUtil.getObjectName(serviceId),
      new Attribute(JmxConstants.SERVICE_POLICIES_ATTRIBUTE_NAME,
        "<sunman:Policies>...</sunman:Policies>"));
    connector.close();
    }
}

19.9.4. Client Authentication and Authorization

JMX clients can be required to authenticate and their actions can be limited. The Sun JDK JMX implementation provides several methods, including JAAS, to take care of authentication and authorization. They are extensively discussed in this blog entry. Here we only cover the simplest use case that is discussed in that blog, where JMX connector environment properties point to one password file and one access file.

Create one file named e.g. jmx.password with this content:

monitorRole mrpasswd
controlRole crpasswd

This defines two users monitorRole and controlRole and their passwords. Next create a file jmx.access with this content:

monitorRole readonly
controlRole readwrite

This allows user monitorRole to only read data, while controlRole may also write. The Metro management MBean only provides one attribute and that attribute is write-only, i.e. the only case where a read-only user makes sense would be for listening to notifications.

Now you can configure the service management interface with these settings:

<sunman:ManagedService id="service-id">
    <sunman:CommunicationServerImplementations>
        <sunman:CommunicationServerImplementation>
            <sunman:JmxConnectorServerEnvironment>
                <jmx.remote.x.password.file>
                    /path/to/jmx.password
                </jmx.remote.x.password.file>
                <jmx.remote.x.access.file>
                    /path/to/jmx.access
                </jmx.remote.x.access.file>
            </sunman:JmxConnectorServerEnvironment>
        </sunman:CommunicationServerImplementation>
    </sunman:CommunicationServerImplementations>
</sunman:ManagedService>

Finally, the client code needs to explicitly set the password before it connects to the JMX agent:

import com.sun.xml.ws.api.config.management.jmx.JmxConstants;
import com.sun.xml.ws.api.config.management.jmx.JmxUtil;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.management.Attribute;
import javax.management.MBeanServerConnection;
import javax.management.JMException;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class Client {

public static void main(String[] args)
  throws MalformedURLException, IOException, JMException {
    final String serviceId = "service-1";
    // The RMI registry is running on the local host in this case.
    JMXServiceURL url = new JMXServiceURL(
      JmxConstants.JMX_SERVICE_URL_DEFAULT_PREFIX + serviceId);
    // Set client credentials
    HashMap<String, Object> env = new HashMap<String, Object>();
    String[] creds = {"controlRole", "crpasswd"};
    env.put(JMXConnector.CREDENTIALS, creds);
    JMXConnector connector = JMXConnectorFactory.connect(url, env);
    MBeanServerConnection connection = connector.getMBeanServerConnection();
    connection.setAttribute(
      JmxUtil.getObjectName(serviceId),
      new Attribute(JmxConstants.SERVICE_POLICIES_ATTRIBUTE_NAME,
        "<sunman:Policies>...</sunman:Policies>"));
    connector.close();
    }
}

Terms of Use; Privacy Policy; Copyright ©2013-2014 (revision 20140418.2d69abc)
 
 
Close
loading
Please Confirm
Close