/*
* Copyright 2008-2009 LinkedIn, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package voldemort.server.jmx;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import org.apache.log4j.Logger;
import voldemort.annotations.jmx.JmxManaged;
import voldemort.cluster.Cluster;
import voldemort.common.service.AbstractService;
import voldemort.common.service.ServiceType;
import voldemort.common.service.VoldemortService;
import voldemort.server.StoreRepository;
import voldemort.server.VoldemortServer;
import voldemort.store.Store;
import voldemort.utils.ByteArray;
import voldemort.utils.JmxUtils;
/**
* A service that manages JMX registration
*
*
*/
@JmxManaged(description = "The JMX service")
public class JmxService extends AbstractService {
private final Logger logger = Logger.getLogger(JmxService.class);
private final MBeanServer mbeanServer;
private final VoldemortServer server;
private final Cluster cluster;
private final List<VoldemortService> services;
private final Set<ObjectName> registeredBeans;
private final StoreRepository storeRepository;
public JmxService(VoldemortServer server,
Cluster cluster,
StoreRepository storeRepository,
Collection<VoldemortService> services) {
super(ServiceType.JMX);
this.server = server;
this.cluster = cluster;
this.services = new ArrayList<VoldemortService>(services);
this.mbeanServer = ManagementFactory.getPlatformMBeanServer();
this.registeredBeans = new HashSet<ObjectName>();
this.storeRepository = storeRepository;
}
@Override
protected void startInner() {
registerBean(server, JmxUtils.createObjectName(VoldemortServer.class));
registerBean(cluster, JmxUtils.createObjectName(Cluster.class));
for(VoldemortService service: services)
registerBean(service, JmxUtils.createObjectName(service.getClass()));
for(Store<ByteArray, byte[], byte[]> store: this.storeRepository.getAllStorageEngines()) {
if(server.getVoldemortConfig().isEnableJmxClusterName())
registerBean(store,
JmxUtils.createObjectName(this.cluster.getName()
+ "."
+ JmxUtils.getPackageName(store.getClass()),
store.getName()));
else
registerBean(store,
JmxUtils.createObjectName(JmxUtils.getPackageName(store.getClass()),
store.getName()));
}
}
@Override
protected void stopInner() {
for(ObjectName name: registeredBeans)
JmxUtils.unregisterMbean(mbeanServer, name);
registeredBeans.clear();
}
public void registerServices(List<VoldemortService> services) {
for(VoldemortService service: services) {
registerBean(service, JmxUtils.createObjectName(service.getClass()));
}
}
public void unregisterServices(List<VoldemortService> services) {
for(VoldemortService service: services) {
unregisterBean(JmxUtils.createObjectName(service.getClass()));
}
}
private void registerBean(Object o, ObjectName name) {
synchronized(registeredBeans) {
try {
if(mbeanServer.isRegistered(name)) {
logger.warn("Overwriting mbean " + name);
JmxUtils.unregisterMbean(mbeanServer, name);
}
JmxUtils.registerMbean(mbeanServer, JmxUtils.createModelMBean(o), name);
this.registeredBeans.add(name);
} catch(Exception e) {
logger.error("Error registering bean with name '" + name + "':", e);
}
}
}
private void unregisterBean(ObjectName name) {
synchronized(registeredBeans) {
try {
if(mbeanServer.isRegistered(name)) {
logger.warn("Overwriting mbean " + name);
JmxUtils.unregisterMbean(mbeanServer, name);
}
if(registeredBeans.contains(name)) {
registeredBeans.remove(name);
}
} catch(Exception e) {
logger.error("Error unregistering bean with name '" + name + "':", e);
}
}
}
}