Автор оригинала: Pankaj Kumar.
В последнем уроке мы узнали об основах JMX и о том, как мы можем использовать JConsole для управления MBeans . Сегодня мы рассмотрим пример клиента java jmx и проверку подлинности на основе ролей с помощью файлов конфигурации.
Клиент Java JMX
Хотя JConsole предоставляет графическое представление, но оно требует человеческих усилий для работы с MBean и не подходит там, где вы хотите периодически вызывать некоторые функции MBean. Например, у вас есть MBean, который предоставляет текущее состояние приложения, и вы хотите вызывать его для проверки состояния каждые 10 минут. В этом случае очень полезно иметь программу java, которая может работать как клиент JMX для подключения к серверу JMX MBean и вызова операций MBean.
Пример клиента JMX
Здесь мы напишем java-программу, которая может подключаться к серверу MBean и создавать прокси-приложение для вызова операций MBean. Я буду использовать приложение MBean, созданное в учебнике JMX, и использовать нашу клиентскую программу для подключения к MBean. Позже мы проверим, как обеспечить безопасность нашего сервера MBean с помощью файлов конфигурации JMX для доступа на основе ролей и как мы можем использовать учетные данные в клиенте JMX для подключения к серверу MBean с правильной ролью.
Прежде чем писать клиентское приложение JMX, нам нужно знать порт, на котором работает сервер MBean. Также для начала мы отключим всю аутентификацию. Мы можем сделать все это, передав правильные параметры java.
Поэтому я начну свой MBean со следующей команды. Обратите внимание на параметры java, указанные для порта сервера MBean, и отключение SSL и аутентификации.
pankaj@JD:~/CODE/JavaProject/bin$ java -cp . -Dcom.sun.management.jmxremote.port=1234 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false com.journaldev.jmx.SystemConfigManagement Thread Count=10:::Schema Name=default Thread Count=10:::Schema Name=default Thread Count=10:::Schema Name=default ...
URL-АДРЕС JMX
Чтобы клиентское приложение получило прокси-сервер MBean, сначала нам нужно создать JMXServiceURL
, передав хост и порт RMI.
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + HOST + ":" + PORT + "/jmxrmi");
После этого мы должны получить экземпляр JMX Connector
, используя его заводской класс.
JMXConnector jmxConnector = JMXConnectorFactory.connect(url);
После этого мы получаем MBeanServerConnection
из экземпляра соединителя JMX.
MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection();
После этого мы получаем экземпляр прокси-сервера MBean с помощью MBeanServerInvocationHandler
.
//ObjectName should be same as your MBean name ObjectName mbeanName = new ObjectName("com.journaldev.jmx:type=SystemConfig"); //Get MBean proxy instance that will be used to make calls to registered MBean SystemConfigMBean mbeanProxy = (SystemConfigMBean) MBeanServerInvocationHandler.newProxyInstance( mbeanServerConnection, mbeanName, SystemConfigMBean.class, true);
Как только мы получим экземпляр прокси-сервера, мы сможем вызвать любую операцию, предоставленную MBean.
Пример клиентской программы Java JMX
Вот полная клиентская программа JMX, которая подключается к серверу MBean, получает экземпляр прокси-сервера MBean конфигурации системы и вызывает открытые методы.
package com.journaldev.jmx; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.management.MBeanServerConnection; import javax.management.MBeanServerInvocationHandler; import javax.management.MalformedObjectNameException; import javax.management.ObjectName; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; public class SystemConfigClient { public static final String HOST = "localhost"; public static final String PORT = "1234"; public static void main(String[] args) throws IOException, MalformedObjectNameException { JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + HOST + ":" + PORT + "/jmxrmi"); JMXConnector jmxConnector = JMXConnectorFactory.connect(url); MBeanServerConnection mbeanServerConnection = jmxConnector.getMBeanServerConnection(); //ObjectName should be same as your MBean name ObjectName mbeanName = new ObjectName("com.journaldev.jmx:type=SystemConfig"); //Get MBean proxy instance that will be used to make calls to registered MBean SystemConfigMBean mbeanProxy = (SystemConfigMBean) MBeanServerInvocationHandler.newProxyInstance( mbeanServerConnection, mbeanName, SystemConfigMBean.class, true); //let's make some calls to mbean through proxy and see the results. System.out.println("Current SystemConfig::" + mbeanProxy.doConfig()); mbeanProxy.setSchemaName("NewSchema"); mbeanProxy.setThreadCount(5); System.out.println("New SystemConfig::" + mbeanProxy.doConfig()); //let's terminate the mbean by making thread count as 0 mbeanProxy.setThreadCount(0); //close the connection jmxConnector.close(); } }
Перед запуском клиентского приложения убедитесь, что наше приложение MBean запущено с помощью команды, указанной в начале сообщения. Когда мы выполним клиентское приложение, оно выведет следующее в консоль.
Current SystemConfig::No of Threads=10 and DB Schema Name=default New SystemConfig::No of Threads=5 and DB Schema Name=NewSchema
Если вы проверите терминал, в котором запущено наше приложение MBean, вы найдете следующий вывод до завершения программы.
Thread Count=10:::Schema Name=default Thread Count=10:::Schema Name=default Thread Count=0:::Schema Name=NewSchema
Итак, теперь мы знаем, как написать клиентскую программу JMX, которая может подключаться к удаленному серверу MBean и создавать прокси-сервер MBean для использования атрибутов и операций, предоставляемых MBean.
Аутентификация на основе ролей JMX
Давайте начнем настраивать наш MBean для проверки подлинности на основе ролей. Для этого нам нужно создать три файла.
Файл доступа JMX : Этот файл содержит роли и доступ, связанные с ролями. Типы доступа:
только для чтения
илизапись для чтения
. Для нашей цели создайтеjmxremote.access
файл со следующим содержимым.Файл доступа JMX
: Этот файл содержит роли и доступ, связанные с ролями. Типы доступа:
только для чтения
или запись для чтения
. Для нашей цели создайте
jmxremote.access
файл со следующим содержимым.Таким образом, роль-это "моя роль", и у нее есть доступ для чтения и записи к Средствам.
Файл пароля JMX
: Этот файл содержит пароль различных ролей, которые у нас есть, пароль является открытым текстом, поэтому Java добавляет ограничение, согласно которому только владелец приложения должен иметь доступ к файлу для чтения и записи.
Создайте файлjmxremote.password со следующим содержимым.
Создайте файл
jmxremote.passwordсо следующим содержимым.
После создания файла измените разрешение с помощью команды
Как только все необходимые файлы будут собраны, мы запустим наше приложение JMX MBean со следующей командой.
java -cp . -Dcom.sun.management.config.file=management.properties com.journaldev.jmx.SystemConfigManagement
Теперь, если вы попытаетесь запустить наше клиентское приложение JMX, оно выдаст следующее исключение.
Exception in thread "main" java.lang.SecurityException: Authentication failed! Credentials required at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticationFailure(JMXPluggableAuthenticator.java:211) at com.sun.jmx.remote.security.JMXPluggableAuthenticator.authenticate(JMXPluggableAuthenticator.java:163) at sun.management.jmxremote.ConnectorBootstrap$AccessFileCheckerAuthenticator.authenticate(ConnectorBootstrap.java:219) at javax.management.remote.rmi.RMIServerImpl.doNewClient(RMIServerImpl.java:232)
Сообщение об исключении ясно показывает, что нам необходимо предоставить учетные данные для доступа к JMX MBean. Чтобы предоставить учетные данные, нам необходимо добавить следующий код в нашу клиентскую программу.
//for passing credentials for password Mapenv = new HashMap<>(); String[] credentials = {"myrole", "MYP@SSWORD"}; env.put(JMXConnector.CREDENTIALS, credentials); JMXConnector jmxConnector = JMXConnectorFactory.connect(url, env);
Обратите внимание, что конструктор изменен для предоставления учетных данных при подключении к серверу JMX MBean. Теперь программа будет работать нормально и выдавать те же результаты, что и ранее.
Это все для примера клиента Java JMX и проверки подлинности JMX для доступа на основе ролей.