GestoreRisorseJMX.java
- /*
- * GovWay - A customizable API Gateway
- * https://govway.org
- *
- * Copyright (c) 2005-2025 Link.it srl (https://link.it).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3, as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- package org.openspcoop2.utils.jmx;
- import java.lang.reflect.Constructor;
- import java.lang.reflect.Method;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Properties;
- import javax.management.MBeanServer;
- import javax.management.ObjectName;
- import javax.naming.Context;
- import org.openspcoop2.utils.LoggerWrapperFactory;
- import org.openspcoop2.utils.resources.ClassLoaderUtilities;
- import org.openspcoop2.utils.resources.GestoreJNDI;
- import org.slf4j.Logger;
- /**
- * Gestore risorse JMX utilizzate da OpenSPCoop
- *
- * @author Poli Andrea (apoli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class GestoreRisorseJMX {
- /** MBeanServer */
- private MBeanServer mbeanServer = null;
- /** MBeanServerConnection */
- private Object mbeanServerConnection = null;
- /** Logger */
- protected Logger log = null;
- protected void logInfo(String msg) {
- if(this.log!=null && this.logActive) {
- this.log.info(msg);
- }
- }
- protected void logDebug(String msg, Throwable e) {
- if(this.log!=null && this.logActive) {
- this.log.debug(msg, e);
- }
- }
- protected void logError(String msg, Throwable e) {
- if(this.log!=null && this.logActive) {
- this.log.error(msg, e);
- }
- }
- private boolean logActive = true;
- public boolean isLogActive() {
- return this.logActive;
- }
- public void setLogActive(boolean logActive) {
- this.logActive = logActive;
- }
-
- private static final String MBEAN_SERVER_CONNECTION = "javax.management.MBeanServerConnection";
-
- /** JMX Name */
- private List<ObjectName> jmxNames = new ArrayList<>();
-
-
- /**
- * Inizializzazione del Gestore delle risorse JMX
- */
- public GestoreRisorseJMX() throws RisorseJMXException{
- this(null,null,null);
- }
- public GestoreRisorseJMX(Logger logger) throws RisorseJMXException{
- this(null,null,logger);
- }
- /**
- * Inizializzazione del Gestore delle risorse JMX
- *
- * @param jndiNameMBeanServer Nome JNDI del MBean Server
- * @param jndiContext Contesto jndi per localizzare il MBean Server
- */
- public GestoreRisorseJMX(String jndiNameMBeanServer,java.util.Properties jndiContext) throws RisorseJMXException{
- this(jndiNameMBeanServer,jndiContext,null,null);
- }
- public GestoreRisorseJMX(String jndiNameMBeanServer,java.util.Properties jndiContext,Logger logger) throws RisorseJMXException{
- this(jndiNameMBeanServer,jndiContext,logger,null);
- }
- public GestoreRisorseJMX(String jndiNameMBeanServer,java.util.Properties jndiContext,Logger logger,Logger loggerConsole) throws RisorseJMXException{
- this(jndiNameMBeanServer,jndiContext,
- null,null,null,null,null,
- logger,loggerConsole);
- }
-
- public GestoreRisorseJMX(String tipoApplicationServer, String factory, String serverUrl, String username, String password) throws RisorseJMXException{
- this(null,null,
- tipoApplicationServer,factory,serverUrl,username,password,
- null,null);
- }
- public GestoreRisorseJMX(String tipoApplicationServer, String factory, String serverUrl, String username, String password,
- Logger logger) throws RisorseJMXException{
- this(null,null,
- tipoApplicationServer,factory,serverUrl,username,password,
- logger,null);
- }
- public GestoreRisorseJMX(String tipoApplicationServer, String factory, String serverUrl, String username, String password,
- Logger logger,Logger loggerConsole) throws RisorseJMXException{
- this(null,null,
- tipoApplicationServer,factory,serverUrl,username,password,
- logger,loggerConsole);
- }
-
- private GestoreRisorseJMX(String modalita1JndiNameMBeanServer,java.util.Properties modalita1JndiContext,
- String modalita2TipoApplicationServer, String modalita2Factory, String modalita2ServerUrl, String modalita2Username, String modalita2Password,
- Logger logger,Logger loggerConsole) throws RisorseJMXException{
-
- // log
- if(logger==null){
- this.log = LoggerWrapperFactory.getLogger(GestoreRisorseJMX.class);
- }
- else{
- this.log = logger;
- }
-
- // logConsole
- if(loggerConsole==null){
- loggerConsole = LoggerWrapperFactory.getLogger("govway.startup");
- }
-
- try{
- // Ci sono tre modi per avere l'MBean SERVER
-
- // 1: da JNDI
- if(modalita1JndiNameMBeanServer!=null){
- GestoreJNDI jndi = new GestoreJNDI(modalita1JndiContext);
- this.mbeanServer = (javax.management.MBeanServer) jndi.lookup(modalita1JndiNameMBeanServer);
- if(this.mbeanServer==null)
- throw new RisorseJMXException("MBeanServer ["+modalita1JndiNameMBeanServer+"] non trovato");
- else{
- String msg = "Attivata gestione jmx attraverso MBeanServer ["+modalita1JndiNameMBeanServer+"]: "+this.mbeanServer.toString();
- if(logger==null) {
- loggerConsole.info(msg);
- }
- this.logInfo(msg);
- }
- }
- // 2: via url
- else if(modalita2TipoApplicationServer!=null && !"".equals(modalita2TipoApplicationServer)){
- if(modalita2Factory==null || "".equals(modalita2Factory)){
- throw new RisorseJMXException("Parametro 'factory' non fornito");
- }
- if(modalita2ServerUrl==null || "".equals(modalita2ServerUrl)){
- throw new RisorseJMXException("Parametro 'serverUrl' non fornito");
- }
- if(modalita2TipoApplicationServer.equals("jboss7") ||
- (modalita2TipoApplicationServer!=null && modalita2TipoApplicationServer.startsWith("wildfly")) ||
- modalita2TipoApplicationServer.startsWith("tomcat")){
-
- Class<?>jmxServiceURLClass = Class.forName("javax.management.remote.JMXServiceURL");
- Constructor<?> constructorJmxServiceURLClass = jmxServiceURLClass.getConstructor(String.class);
- Object serviceURL = constructorJmxServiceURLClass.newInstance(modalita2ServerUrl);
- java.util.Map<String, Object> env = null;
- if(modalita2Username!=null && modalita2Password!=null){
- String[] creds = {modalita2Username, modalita2Password};
- env = new HashMap<>();
- env.put("jmx.remote.credentials", creds);
- }
-
- Class<?>jmxConnectorFactoryClass = Class.forName("javax.management.remote.JMXConnectorFactory");
- Method connect = jmxConnectorFactoryClass.getMethod("connect", jmxServiceURLClass, java.util.Map.class);
- Object jmxConnector = connect.invoke(null, serviceURL, env);
-
- Class<?>jmxConnectorClass = Class.forName("javax.management.remote.JMXConnector");
- Method getMBeanServerConnection = jmxConnectorClass.getMethod("getMBeanServerConnection");
- this.mbeanServerConnection = getMBeanServerConnection.invoke(jmxConnector);
- }
- else{
- Properties properties = new Properties();
- properties.put(Context.INITIAL_CONTEXT_FACTORY, modalita2Factory);
- properties.put(Context.PROVIDER_URL, modalita2ServerUrl);
- GestoreJNDI jndi = new GestoreJNDI(properties);
- this.mbeanServerConnection = jndi.lookup("jmx/invoker/RMIAdaptor");
-
- if(modalita2Username!=null && modalita2Password!=null){
-
- Class<?>simplePrincipalClass = Class.forName("org.jboss.security.SimplePrincipal");
- Constructor<?> constructorPrincipalClass = simplePrincipalClass.getConstructor(String.class);
- Object simplePrincipal = constructorPrincipalClass.newInstance(modalita2Username);
-
- Class<?>securityAssociationClass = Class.forName("org.jboss.security.SecurityAssociation");
- Method setPrincipal = securityAssociationClass.getMethod("setPrincipal", simplePrincipalClass);
- setPrincipal.invoke(null, simplePrincipal);
- Method setCredential = securityAssociationClass.getMethod("setCredential", String.class);
- setCredential.invoke(null, modalita2Password);
- }
-
- }
- }
-
-
- // 3: Prendendolo dall'application server, cercandone uno di default
- else{
- java.util.ArrayList<?> lServer = javax.management.MBeanServerFactory.findMBeanServer(null);
- if(lServer==null){
- throw new RisorseJMXException("Lista di MBean Server di default non trovata (MBeanServerFactory.findMBeanServer)");
- }else{
- if(lServer.isEmpty()){
- throw new RisorseJMXException("Lista di MBean Server di default vuota");
- }else{
- java.util.Iterator<?> it = lServer.iterator();
- if(it.hasNext()){
- this.mbeanServer = (javax.management.MBeanServer) it.next();
- if(this.mbeanServer==null)
- throw new RisorseJMXException("MBeanServer di default non trovato");
- else{
- String msg = "Attivata gestione jmx attraverso MBeanServer: "+this.mbeanServer.toString();
- if(logger==null)
- loggerConsole.info(msg);
- this.logInfo(msg);
- }
- }else{
- throw new RisorseJMXException("Lista di MBean Server di default vuota ?");
- }
- }
- }
- }
-
- }catch(Exception e){
- this.logError("Riscontrato errore durante l'inizializzazione del gestore delle RisorseJMX: "+e.getMessage(),e);
- throw new RisorseJMXException("Riscontrato errore durante l'inizializzazione del gestore delle RisorseJMX: "+e.getMessage(),e);
- }
- }
-
-
-
-
-
- /**
- * Registrazione del MBean generico
- *
- * @throws RisorseJMXException
- */
- public void registerMBean(Class<?> c,String nome)throws RisorseJMXException{
- this.registerMBean(c, CostantiJMX.JMX_DOMINIO,CostantiJMX.JMX_TYPE, nome, true);
- }
- public void registerMBean(Class<?> c,String dominio,String type,String nome)throws RisorseJMXException{
- this.registerMBean(c, dominio, type, nome, true);
- }
- public void registerMBean(Class<?> c,String dominio,String type,String nome, boolean throwExceptionAlreadyExists)throws RisorseJMXException{
- try{
- javax.management.ObjectName jmxName =
- new javax.management.ObjectName(dominio,type,nome);
- if(this.mbeanServer==null){
- throw new RisorseJMXException("Operazione di registrazione permessa solo se il gestore viene inizializzato con il costruttore di default o indicando l'MBeanServer");
- }
- this.mbeanServer.registerMBean(ClassLoaderUtilities.newInstance(c), jmxName);
- this.jmxNames.add(jmxName);
- }catch(Exception e){
- if((e instanceof javax.management.InstanceAlreadyExistsException) && !throwExceptionAlreadyExists){
- this.logDebug("Risorsa JMX ["+nome+"] giĆ esistente: "+e.getMessage(),e);
- }
- else{
- this.logError("Riscontrato errore durante l'inizializzazione della risorsa JMX ["+nome+"]: "+e.getMessage(),e);
- throw new RisorseJMXException("Riscontrato errore durante l'inizializzazione della risorsa JMX ["+nome+"]: "+e.getMessage(),e);
- }
- }
-
- }
-
-
- /**
- * Eliminazione dei MBean registrati
- */
- public void unregisterMBeans(){
- for(int i=0; i<this.jmxNames.size(); i++){
- javax.management.ObjectName jmxName = this.jmxNames.get(i);
- try{
- if(this.mbeanServer==null){
- throw new RisorseJMXException("Operazione di cancellazione permessa solo se il gestore viene inizializzato con il costruttore di default o indicando l'MBeanServer");
- }
- this.mbeanServer.unregisterMBean(jmxName);
- this.logInfo("Unbound della risorsa JMX ["+jmxName.toString()+"]");
- }catch(Exception e){
- this.logError("Riscontrato errore durante l'unbound della risorsa JMX ["+jmxName.toString()+"]: "+e.getMessage(),e);
- }
- }
- }
-
-
- public Object getAttribute(String nomeRisorsa,String nomeAttributo)throws RisorseJMXException{
- return this.getAttribute(CostantiJMX.JMX_DOMINIO,CostantiJMX.JMX_TYPE,nomeRisorsa,nomeAttributo);
- }
- public Object getAttribute(String dominio,String tipo,String nomeRisorsa,String nomeAttributo)throws RisorseJMXException{
- try{
- ObjectName name = new ObjectName(dominio,tipo,nomeRisorsa);
- if(this.mbeanServerConnection!=null){
- Class<?> c = Class.forName(MBEAN_SERVER_CONNECTION);
- Method m = c.getMethod("getAttribute", ObjectName.class, String.class);
- return m.invoke(this.mbeanServerConnection, name, nomeAttributo);
- }
- else{
- return this.mbeanServer.getAttribute(name, nomeAttributo);
- }
- }catch(Exception e){
- String msg = "Riscontrato errore durante la lettura dell'attributo ["+nomeAttributo+"] nella risorsa ["+nomeRisorsa+"]: "+e.getMessage();
- this.logError(msg,e);
- throw new RisorseJMXException(msg,e);
- }
- }
-
- public void setAttribute(String nomeRisorsa,String nomeAttributo, Object value)throws RisorseJMXException{
- this.setAttribute(CostantiJMX.JMX_DOMINIO,CostantiJMX.JMX_TYPE,nomeRisorsa,nomeAttributo,value);
- }
- public void setAttribute(String dominio,String tipo,String nomeRisorsa,String nomeAttributo, Object value)throws RisorseJMXException{
- try{
- ObjectName name = new ObjectName(dominio,tipo,nomeRisorsa);
- javax.management.Attribute attribute = new javax.management.Attribute(nomeAttributo, value);
- if(this.mbeanServerConnection!=null){
- Class<?> c = Class.forName(MBEAN_SERVER_CONNECTION);
- Method m = c.getMethod("setAttribute", ObjectName.class, javax.management.Attribute.class);
- m.invoke(this.mbeanServerConnection, name, nomeAttributo);
- }
- else{
- this.mbeanServer.setAttribute(name, attribute);
- }
- }catch(Exception e){
- String msg = "Riscontrato errore durante l'aggiornamento dell'attributo ["+nomeAttributo+"] della risorsa ["+nomeRisorsa+"]: "+e.getMessage();
- this.logError(msg,e);
- throw new RisorseJMXException(msg,e);
- }
- }
-
-
- public Object invoke(String nomeRisorsa,String nomeMetodo,Object[]params,String[]signature)throws RisorseJMXException{
- return this.invoke(CostantiJMX.JMX_DOMINIO,CostantiJMX.JMX_TYPE,nomeRisorsa,nomeMetodo,params,signature);
- }
- public Object invoke(String dominio,String tipo,String nomeRisorsa,String nomeMetodo,Object[]params,String[]signature)throws RisorseJMXException{
- try{
- ObjectName name = new ObjectName(dominio,tipo,nomeRisorsa);
- if(this.mbeanServerConnection!=null){
- Class<?> c = Class.forName(MBEAN_SERVER_CONNECTION);
- Method m = c.getMethod("invoke", ObjectName.class, String.class, Object[].class, String[].class);
- return m.invoke(this.mbeanServerConnection, name, nomeMetodo, params, signature);
- }
- else{
- return this.mbeanServer.invoke(name, nomeMetodo, params, signature);
- }
- }catch(Exception e){
- String msg = "Riscontrato errore durante l'invocazione del metodo ["+nomeMetodo+"] della risorsa ["+nomeRisorsa+"]: "+e.getMessage();
- this.logError(msg,e);
- throw new RisorseJMXException(msg,e);
- }
- }
-
- }