JmxDataSource.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */


  20. package org.openspcoop2.utils.datasource;

  21. import java.util.Iterator;

  22. import javax.management.Attribute;
  23. import javax.management.AttributeList;
  24. import javax.management.AttributeNotFoundException;
  25. import javax.management.DynamicMBean;
  26. import javax.management.InvalidAttributeValueException;
  27. import javax.management.JMException;
  28. import javax.management.MBeanAttributeInfo;
  29. import javax.management.MBeanConstructorInfo;
  30. import javax.management.MBeanException;
  31. import javax.management.MBeanInfo;
  32. import javax.management.MBeanOperationInfo;
  33. import javax.management.MBeanParameterInfo;
  34. import javax.management.NotificationBroadcasterSupport;
  35. import javax.management.ReflectionException;

  36. import org.openspcoop2.utils.LoggerWrapperFactory;
  37. import org.slf4j.Logger;




  38. /**
  39.  * Implementazione JMX per la gestione delle risorse
  40.  *  
  41.  * @author Poli Andrea (apoli@link.it)
  42.  * @author $Author$
  43.  * @version $Rev$, $Date$
  44.  */
  45. public class JmxDataSource extends NotificationBroadcasterSupport implements DynamicMBean {

  46.     /** Nomi attributi */
  47.     public static final String NUMERO_DATASOURCE = "datasources";
  48.    
  49.     /** Nomi metodi */
  50.     public static final String CONNESSIONI_ALLOCATE = "getUsedConnections";
  51.     public static final String INFORMAZIONI_DATABASE = "getInformazioniDatabase";
  52.     public static final String DATASOURCE_CREATI = "getDatasources";
  53.     public static final String DATASOURCE_CREATI_METHOD2 = "listDatasources"; // per farlo comparire in jmx-console

  54.    
  55.     public static final String MSG_OPERAZIONE_NON_EFFETTUATA = "Operazione non riuscita: ";
  56.    
  57.     /** getAttribute */
  58.     @Override
  59.     public Object getAttribute(String attributeName) throws AttributeNotFoundException,MBeanException,ReflectionException{
  60.        
  61.         if( (attributeName==null) || (attributeName.equals("")) )
  62.             throw new IllegalArgumentException("Il nome dell'attributo e' nullo o vuoto");
  63.        
  64.         if(attributeName.equals(JmxDataSource.NUMERO_DATASOURCE))
  65.             return DataSourceFactory.sizeDatasources();
  66.        
  67.         throw new AttributeNotFoundException("Attributo "+attributeName+" non trovato");
  68.     }
  69.    
  70.     /** getAttributes */
  71.     @Override
  72.     public AttributeList getAttributes(String [] attributesNames){
  73.        
  74.         if(attributesNames==null)
  75.             throw new IllegalArgumentException("Array nullo");
  76.        
  77.         AttributeList list = new AttributeList();
  78.         for (int i=0; i<attributesNames.length; i++){
  79.             try{
  80.                 list.add(new Attribute(attributesNames[i],getAttribute(attributesNames[i])));
  81.             }catch(JMException ex){}
  82.         }
  83.         return list;
  84.     }
  85.    
  86.     /** setAttribute */
  87.     @Override
  88.     public void setAttribute(Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException{
  89.        
  90.         if( attribute==null )
  91.             throw new IllegalArgumentException("Il nome dell'attributo e' nullo");
  92.        
  93.         try{
  94.            
  95.             if(attribute.getName().equals(JmxDataSource.NUMERO_DATASOURCE)){
  96.                 // READ ONLY
  97.             }
  98.             else
  99.                 throw new AttributeNotFoundException("Attributo "+attribute.getName()+" non trovato");
  100.            
  101.         }catch(ClassCastException ce){
  102.             throw new InvalidAttributeValueException("il tipo "+attribute.getValue().getClass()+" dell'attributo "+attribute.getName()+" non e' valido");
  103.         }catch(JMException j){
  104.             throw new MBeanException(j);
  105.         }
  106.        
  107.     }
  108.    
  109.     /** setAttributes */
  110.     @Override
  111.     public AttributeList setAttributes(AttributeList list){
  112.        
  113.         if(list==null)
  114.             throw new IllegalArgumentException("Lista degli attributi e' nulla");
  115.        
  116.         AttributeList ret = new AttributeList();
  117.         Iterator<?> it = ret.iterator();
  118.        
  119.         while(it.hasNext()){
  120.             try{
  121.                 Attribute attribute = (Attribute) it.next();
  122.                 setAttribute(attribute);
  123.                 ret.add(attribute);
  124.             }catch(JMException ex){}
  125.         }
  126.        
  127.         return ret;
  128.        
  129.     }
  130.    
  131.     /** invoke */
  132.     @Override
  133.     public Object invoke(String actionName, Object[]params, String[]signature) throws MBeanException,ReflectionException{
  134.        
  135.         if( (actionName==null) || (actionName.equals("")) )
  136.             throw new IllegalArgumentException("Nessuna operazione definita");
  137.        
  138.         if(actionName.equals(JmxDataSource.CONNESSIONI_ALLOCATE)){
  139.            
  140.             if(params.length != 1)
  141.                 throw new MBeanException(new Exception("["+JmxDataSource.CONNESSIONI_ALLOCATE+"] Lunghezza parametri non corretta: "+params.length));
  142.            
  143.             String param1 = null;
  144.             if(params[0]!=null && !"".equals(params[0])){
  145.                 param1 = (String)params[0];
  146.             }
  147.             if(param1==null){
  148.                 throw new MBeanException(new Exception("Identificativo del datasource non fornito"));
  149.             }
  150.            
  151.             return this.getUsedDBConnections(param1);
  152.         }
  153.        
  154.         else if(actionName.equals(JmxDataSource.INFORMAZIONI_DATABASE)){
  155.            
  156.             if(params.length != 1)
  157.                 throw new MBeanException(new Exception("["+JmxDataSource.INFORMAZIONI_DATABASE+"] Lunghezza parametri non corretta: "+params.length));
  158.            
  159.             String param1 = null;
  160.             if(params[0]!=null && !"".equals(params[0])){
  161.                 param1 = (String)params[0];
  162.             }
  163.             if(param1==null){
  164.                 throw new MBeanException(new Exception("Identificativo del datasource non fornito"));
  165.             }
  166.            
  167.             return this.getInformazioniDatabase(param1);
  168.         }
  169.        
  170.         else if(actionName.equals(JmxDataSource.DATASOURCE_CREATI) || actionName.equals(JmxDataSource.DATASOURCE_CREATI_METHOD2)){
  171.        
  172.             return this.getDatasource();
  173.            
  174.         }
  175.        
  176.         throw new UnsupportedOperationException("Operazione "+actionName+" sconosciuta");
  177.     }
  178.    
  179.     /* MBean info */
  180.     @Override
  181.     public MBeanInfo getMBeanInfo(){
  182.        
  183.         try{
  184.        
  185.             /*
  186.             if(OpenSPCoopStartup.initialize){
  187.                 this.refresh();
  188.             }
  189.             */
  190.            
  191.             // Per determinare se l'attributo e' leggibile/scrivibile
  192.             final boolean READABLE = true;
  193.             final boolean WRITABLE = true;
  194.            
  195.             // Per determinare se l'attributo e' ricavabile nella forma booleana isAttribute()
  196.             final boolean IS_GETTER = true;
  197.            
  198.             // Descrizione della classe nel MBean
  199.             String className = this.getClass().getName();
  200.             String description = "Datasource allocati con la libreria org.openspcoop2.utils.datasource, premi pulsante (apply changes) per aggiornare i dati";
  201.    
  202.             // MetaData per l'attributo numMsgInConsegna
  203.             MBeanAttributeInfo numDatasourceVAR
  204.                 = new MBeanAttributeInfo(JmxDataSource.NUMERO_DATASOURCE,long.class.getName(),
  205.                             "Numero di Datasource allocati",
  206.                                 READABLE,!WRITABLE,!IS_GETTER);
  207.            
  208.             // MetaData per l'operazione
  209.             MBeanOperationInfo getConnessioneAllocateOP
  210.                 = new MBeanOperationInfo(JmxDataSource.CONNESSIONI_ALLOCATE,"Moduli funzionali che dispongono di una connessione verso il datasource fornito come parametro",
  211.                         new MBeanParameterInfo[]{
  212.                                 new MBeanParameterInfo("idDatasource",String.class.getName(),"Identificativo del datasource")
  213.                             },
  214.                         String.class.getName(),
  215.                         MBeanOperationInfo.ACTION);
  216.            
  217.             // MetaData per l'operazione
  218.             MBeanOperationInfo getInformazioniDatabaseOP
  219.                 = new MBeanOperationInfo(JmxDataSource.INFORMAZIONI_DATABASE,"Informazioni leggibili da una connessione ottenuta dal datasource fornito come parametro",
  220.                         new MBeanParameterInfo[]{
  221.                                 new MBeanParameterInfo("idDatasource",String.class.getName(),"Identificativo del datasource")
  222.                             },
  223.                         String.class.getName(),
  224.                         MBeanOperationInfo.ACTION);
  225.            
  226.             // MetaData per l'operazione
  227.             MBeanOperationInfo getDatasourceAllocatiOP
  228.                 = new MBeanOperationInfo(JmxDataSource.DATASOURCE_CREATI,"Datasource allocati",
  229.                         null,
  230.                         String.class.getName(),
  231.                         MBeanOperationInfo.ACTION);
  232.            
  233.             // MetaData per l'operazione
  234.             MBeanOperationInfo getDatasourceAllocatiOP_method2
  235.                 = new MBeanOperationInfo(JmxDataSource.DATASOURCE_CREATI_METHOD2,"Elenca i datasource allocati",
  236.                         null,
  237.                         String.class.getName(),
  238.                         MBeanOperationInfo.ACTION);
  239.            
  240.             // Mbean costruttore
  241.             MBeanConstructorInfo defaultConstructor = new MBeanConstructorInfo("Default Constructor","Crea e inizializza una nuova istanza del MBean",null);
  242.    
  243.             // Lista attributi
  244.             MBeanAttributeInfo[] attributes = new MBeanAttributeInfo[]{numDatasourceVAR};
  245.            
  246.             // Lista Costruttori
  247.             MBeanConstructorInfo[] constructors = new MBeanConstructorInfo[]{defaultConstructor};
  248.            
  249.             // Lista operazioni
  250.             MBeanOperationInfo[] operations = new MBeanOperationInfo[]{getDatasourceAllocatiOP, getDatasourceAllocatiOP_method2, getConnessioneAllocateOP, getInformazioniDatabaseOP};
  251.            
  252.             return new MBeanInfo(className,description,attributes,constructors,operations,null);
  253.            
  254.         }catch(Exception e){
  255.             //System.out.println("ERRORE: "+e.getMessage());
  256.             //e.printStackTrace(System.out);
  257.             throw new RuntimeException(e.getMessage(),e);
  258.         }
  259.     }
  260.    
  261.    
  262.     /* Variabili per la gestione JMX */
  263.     private Logger log = LoggerWrapperFactory.getLogger(JmxDataSource.class);

  264.     /* Costruttore */
  265.     public JmxDataSource(){
  266.        
  267.     }
  268.    
  269.    
  270.     /* Metodi di management JMX */

  271.     public static final String MSG_NESSUNA_CONNESSIONE_ALLOCATA = "Nessuna connessione allocata";
  272.     public static final String MSG_CONNESSIONI_ALLOCATE = " connessioni allocate: ";
  273.    
  274.     public static final String MSG_NESSUN_DATASOURCE_ALLOCATO = "Nessun datasource allocato";
  275.     public static final String MSG_DATASOURCE_ALLOCATI = " datasource allocati: ";

  276.     public String getUsedDBConnections(String uuidDataSource){
  277.         String[] risorse = null;
  278.         try{
  279.             risorse = DataSourceFactory.getInstance(uuidDataSource).getJmxStatus();
  280.         }catch(Throwable e){
  281.             this.log.error(e.getMessage(),e);
  282.             return MSG_OPERAZIONE_NON_EFFETTUATA+e.getMessage();
  283.         }
  284.         return getResultUsedDBConnections(risorse);
  285.     }
  286.     public static String getResultUsedDBConnections(String[] risorse) {
  287.         if(risorse==null || risorse.length<=0)
  288.             return MSG_NESSUNA_CONNESSIONE_ALLOCATA;
  289.        
  290.         StringBuilder bf = new StringBuilder();
  291.         bf.append(risorse.length+MSG_CONNESSIONI_ALLOCATE+"\n");
  292.         for(int i=0; i<risorse.length; i++){
  293.             bf.append(risorse[i]+"\n");
  294.         }
  295.         return bf.toString();      
  296.     }
  297.    
  298.     public String getInformazioniDatabase(String uuidDataSource){
  299.         try{
  300.             org.openspcoop2.utils.datasource.DataSource ds = DataSourceFactory.getInstance(uuidDataSource);
  301.             return ds.getInformazioniDatabase();
  302.         }catch(Throwable e){
  303.             this.log.error(e.getMessage(),e);
  304.             return MSG_OPERAZIONE_NON_EFFETTUATA+e.getMessage();
  305.         }
  306.     }
  307.    
  308.     public String getDatasource(){
  309.         String[] risorse = null;
  310.         try{
  311.             risorse = DataSourceFactory.getJmxStatus();
  312.         }catch(Throwable e){
  313.             this.log.error(e.getMessage(),e);
  314.             return MSG_OPERAZIONE_NON_EFFETTUATA+e.getMessage();
  315.         }
  316.         return getResultDatasource(risorse);
  317.     }
  318.     public static String getResultDatasource(String[] risorse) {
  319.         if(risorse==null || risorse.length<=0)
  320.             return MSG_NESSUN_DATASOURCE_ALLOCATO;
  321.        
  322.         StringBuilder bf = new StringBuilder();
  323.         bf.append(risorse.length+MSG_DATASOURCE_ALLOCATI+"\n");
  324.         for(int i=0; i<risorse.length; i++){
  325.             bf.append(risorse[i]+"\n");
  326.         }
  327.         return bf.toString();
  328.     }
  329.    
  330. }