Search code examples
springcassandrajmxspring-jmx

How to create JMX client which can interect with multiple jmx server using different serviceUrl


I am using Spring jmx to create jmx client which can interact with Cassandra cluster to get a mbean object attribute Livedicsspaceused.

So this Cassandra cluster had 3 node hence different serviceUrl (each having different ip address).

Now I realize that while creating MBeanServerConnectionFactoryBean bean I can specify only one service URl like below:

@Bean 
MBeanServerConnectionFactoryBean getConnector() {
    MBeanServerConnectionFactoryBean mBeanfactory = new MBeanServerConnectionFactoryBean();
    try {
        mBeanfactory.setServiceUrl("serviceUrl1");
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
    mBeanfactory.setConnectOnStartup(false);
    return mBeanfactory;
}

Then in main I am accessing this as below:

objectName = newObjectName(QueueServicesConstant.MBEAN_OBJ_NAME_LIVE_DISC_USED);
long count = (Long)mBeanFactory.getObject().getAttribute(objectName, QueueServicesConstant.MBEAN_ATTR_NAME_COUNT);

How can i get this value in all three nodes?


Solution

  • This is how I solved the problem ..Instead of using Spring-JMX, I am directly using javax.management apis..So my code below will get any one of the connector which will be sufficient to provide me correct attribute value however it will try to connect to ohther node if it fails to get connector from one server node.

    @SuppressWarnings("restriction")
    private Object getMbeanAttributeValue(String MbeanObectName,
            String attributeName) throws IOException,
            AttributeNotFoundException, InstanceNotFoundException,
            MBeanException, ReflectionException, MalformedObjectNameException {
        Object attributeValue = null;
        JMXConnector jmxc = null;
        try {
            State state = metaTemplate.getSession().getState();
            List<String> serviceUrlList = getJmxServiceUrlList(state
                    .getConnectedHosts());
            jmxc = getJmxConnector(serviceUrlList);
            ObjectName objectName = new ObjectName(MbeanObectName);
            MBeanServerConnection mbsConnection = jmxc
                    .getMBeanServerConnection();
    
            attributeValue = mbsConnection.getAttribute(objectName,
                    attributeName);
        } finally {
            if (jmxc != null)
                jmxc.close();
        }
        return attributeValue;
    }
    
    // This will provide any one of the JMX Connector of cassandra cluster
    @SuppressWarnings("restriction")
    private JMXConnector getJmxConnector(List<String> serviceUrlList)
            throws IOException {
        JMXConnector jmxc = null;
        for (String serviceUrl : serviceUrlList) {
            JMXServiceURL url;
            try {
                url = new JMXServiceURL(serviceUrl);
                jmxc = JMXConnectorFactory.connect(url, null);
                return jmxc;
            } catch (IOException e) {
                log.error(
                        "getJmxConnector: Error while connecting to JMX sereice {} ",
                        serviceUrl, e.getMessage());
            }
        }
        throw new IOException(
                "Not able to connect to any of Cassandra JMX connector.");
    }