View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.services.mbeans;
20  
21  import java.lang.management.ManagementFactory;
22  import java.lang.ref.WeakReference;
23  import java.util.ArrayList;
24  import java.util.Collections;
25  import java.util.Iterator;
26  
27  import javax.management.InstanceNotFoundException;
28  import javax.management.MBeanServer;
29  import javax.management.MalformedObjectNameException;
30  import javax.management.ObjectInstance;
31  import javax.management.ObjectName;
32  
33  import org.apache.logging.log4j.LogManager;
34  import org.apache.logging.log4j.Logger;
35  import org.mycore.common.config.MCRConfiguration2;
36  import org.mycore.common.events.MCRShutdownHandler;
37  import org.mycore.common.events.MCRShutdownHandler.Closeable;
38  
39  public class MCRJMXBridge implements Closeable {
40  
41      static final WeakReference<MCRJMXBridge> SINGLETON = new WeakReference<>(new MCRJMXBridge());
42  
43      private static final Logger LOGGER = LogManager.getLogger(MCRJMXBridge.class);
44  
45      private static java.util.List<WeakReference<ObjectName>> ONAME_LIST = Collections
46          .synchronizedList(new ArrayList<WeakReference<ObjectName>>());
47  
48      private static boolean shutdown;
49  
50      private MCRJMXBridge() {
51          MCRShutdownHandler.getInstance().addCloseable(this);
52      }
53  
54      public static void register(Object mbean, String type, String component) {
55          if (shutdown) {
56              return;
57          }
58          ObjectName name;
59          try {
60              name = getObjectName(type, component);
61          } catch (MalformedObjectNameException e) {
62              e.printStackTrace();
63              return;
64          }
65          MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
66          try {
67              if (mbs.isRegistered(name)) {
68                  unregister(type, component);
69              }
70              mbs.registerMBean(mbean, name);
71              ONAME_LIST.add(new WeakReference<>(name));
72          } catch (Exception e) {
73              e.printStackTrace();
74          }
75  
76      }
77  
78      public static void unregister(String type, String component) {
79          if (shutdown) {
80              return;
81          }
82          ObjectName name;
83          try {
84              name = getObjectName(type, component);
85          } catch (MalformedObjectNameException e) {
86              e.printStackTrace();
87              return;
88          }
89          MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
90          try {
91              if (mbs.isRegistered(name)) {
92                  mbs.unregisterMBean(name);
93              }
94              // As WeakReference does not overwrite Object.equals():
95              ONAME_LIST.removeIf(wr -> name.equals(wr.get()));
96          } catch (Exception e) {
97              e.printStackTrace();
98          }
99  
100     }
101 
102     private static ObjectName getObjectName(String type, String component) throws MalformedObjectNameException {
103         return new ObjectName(
104             MCRConfiguration2.getString("MCR.NameOfProject").orElse("MyCoRe-Application").replace(':', ' ')
105                 + ":type="
106                 + type + ",component=" + component);
107     }
108 
109     @Override
110     public void prepareClose() {
111         shutdown = true;
112     }
113 
114     @Override
115     public void close() {
116         LOGGER.debug("Shutting down {}", MCRJMXBridge.class.getSimpleName());
117         MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
118         Iterator<WeakReference<ObjectName>> wrIterator = ONAME_LIST.iterator();
119         while (wrIterator.hasNext()) {
120             try {
121                 ObjectName objectName = wrIterator.next().get();
122                 LOGGER.debug("Unregister {}", objectName.getCanonicalName());
123                 mbs.unregisterMBean(objectName);
124                 wrIterator.remove();
125             } catch (Exception e) {
126                 e.printStackTrace();
127             }
128         }
129         SINGLETON.clear();
130     }
131 
132     @Override
133     public int getPriority() {
134         return MCRShutdownHandler.Closeable.DEFAULT_PRIORITY;
135     }
136 
137     public static ObjectInstance getMBean(String type, String component)
138         throws MalformedObjectNameException, InstanceNotFoundException {
139         ObjectName name = getObjectName(type, component);
140 
141         MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
142         if (mbs.isRegistered(name)) {
143             return mbs.getObjectInstance(name);
144         }
145 
146         return null;
147     }
148 }