2
* Copyright Terracotta, Inc.
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
17
package net.sf.ehcache.management;
19
import java.lang.reflect.Constructor;
20
import java.lang.reflect.Method;
21
import java.util.HashMap;
24
import net.sf.ehcache.CacheManager;
25
import net.sf.ehcache.config.ManagementRESTServiceConfiguration;
27
import org.slf4j.Logger;
28
import org.slf4j.LoggerFactory;
32
* ManagementServerLoader is a facility class to access the rest management interface
33
* One would use it form EhCache or QuartzScheduler to start or stop a new rest management interface
34
* or to simply register a cache or a scheduler to an already started management interface.
36
* It uses internally a ResourceClassLoader to load classes from a rest agent jar.
38
* @author Anthony Dahanne
41
public class ManagementServerLoader {
43
private static final String PRIVATE_CLASSPATH = "rest-management-private-classpath";
44
private static final Map<String, Object> MGMT_SVR_BY_BIND = new HashMap<String, Object>();
46
private static final ResourceClassLoader RESOURCE_CLASS_LOADER;
47
private static final Logger LOG = LoggerFactory.getLogger(ManagementServerLoader.class);
50
RESOURCE_CLASS_LOADER = new ResourceClassLoader(PRIVATE_CLASSPATH, CacheManager.class.getClassLoader());
54
* Register a cacheManager to management rest server.
55
* If the server does not exist, starts it.
58
* @param managementRESTServiceConfiguration
60
public static void register(CacheManager cacheManager, ManagementRESTServiceConfiguration managementRESTServiceConfiguration) {
62
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
64
// because some code in Jersey is using the TCCL to resolve some classes
65
Thread.currentThread().setContextClassLoader(RESOURCE_CLASS_LOADER);
67
Class<?> managementServerImplClass = RESOURCE_CLASS_LOADER.loadClass("net.sf.ehcache.management.ManagementServerImpl");
68
Object managementServerImpl = null;
69
if (!MGMT_SVR_BY_BIND.containsKey(managementRESTServiceConfiguration.getBind())) {
70
if (!MGMT_SVR_BY_BIND.isEmpty()) {
71
String alreadyBound = MGMT_SVR_BY_BIND.keySet().iterator().next();
72
managementRESTServiceConfiguration.setBind(alreadyBound);
73
LOG.warn("You can not have several Ehcache management rest agents running in the same ClassLoader; CacheManager "
74
+ cacheManager.getName() + " will be registered to the already running Ehcache management rest agent listening on port "
75
+ alreadyBound + ", the configuration will not be changed");
77
startRestAgent(managementRESTServiceConfiguration, managementServerImplClass);
80
LOG.warn("A previous CacheManager already instanciated the Ehcache Management rest agent, on port "
81
+ managementRESTServiceConfiguration.getBind() + ", the configuration will not be changed for " + cacheManager.getName());
83
managementServerImpl = MGMT_SVR_BY_BIND.get(managementRESTServiceConfiguration.getBind());
84
Method registerMethod = managementServerImplClass.getMethod("register", new Class[] {cacheManager.getClass()});
85
registerMethod.invoke(managementServerImpl, cacheManager);
87
} catch (Exception e) {
88
if (e.getCause() instanceof ClassNotFoundException) {
89
throw new RuntimeException(
90
"Failed to initialize the ManagementRESTService - Did you include ehcache-rest-agent on the classpath?", e);
92
throw new RuntimeException("Failed to instantiate ManagementServer.", e);
95
// setting back the appClassLoader as the TCCL
96
Thread.currentThread().setContextClassLoader(contextClassLoader);
100
private static void startRestAgent(ManagementRESTServiceConfiguration managementRESTServiceConfiguration,
101
Class<?> managementServerImplClass) throws Exception {
102
Object managementServerImpl;
103
Constructor<?> managementServerImplClassConstructor = managementServerImplClass
104
.getConstructor(new Class[] {managementRESTServiceConfiguration.getClass()});
105
managementServerImpl = managementServerImplClassConstructor.newInstance(new Object[] {managementRESTServiceConfiguration});
106
Method startMethod = managementServerImplClass.getMethod("start", new Class[] {});
107
startMethod.invoke(managementServerImpl, new Object[] {});
108
MGMT_SVR_BY_BIND.put(managementRESTServiceConfiguration.getBind(), managementServerImpl);
112
* Unregister a cache manager from a management rest server
113
* If it is the last cache manager bound to this server, stops the server too.
115
* @param registeredMgmtSvrBind
116
* @param cacheManager
118
public static void unregister(String registeredMgmtSvrBind, CacheManager cacheManager) {
119
Object managementServerImpl = MGMT_SVR_BY_BIND.get(registeredMgmtSvrBind);
121
Class<?> managementServerImplClass;
122
boolean removeMgmtSvr = false;
124
managementServerImplClass = RESOURCE_CLASS_LOADER.loadClass("net.sf.ehcache.management.ManagementServerImpl");
125
Method registerMethod = managementServerImplClass.getMethod("unregister", new Class[] {cacheManager.getClass()});
126
registerMethod.invoke(managementServerImpl, cacheManager);
128
Method hasRegisteredMethod = managementServerImplClass.getMethod("hasRegistered", new Class[] {});
129
Boolean hasRegistered = (Boolean) hasRegisteredMethod.invoke(managementServerImpl, new Object[] {});
131
if (!hasRegistered) {
132
removeMgmtSvr = true;
133
Method stopMethod = managementServerImplClass.getMethod("stop", new Class[] {});
134
stopMethod.invoke(managementServerImpl, new Object[] {});
137
} catch (Exception e) {
138
LOG.warn("Failed to shutdown the ManagementRESTService", e);
141
MGMT_SVR_BY_BIND.remove(registeredMgmtSvrBind);