package com.bagri.server.hazelcast.management;
import static com.bagri.core.Constants.pn_cluster_login;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.management.MalformedObjectNameException;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jmx.export.MBeanExportException;
import org.springframework.jmx.export.annotation.AnnotationMBeanExporter;
import com.bagri.core.system.Entity;
import com.bagri.support.util.JMXUtils;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryListener;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import com.hazelcast.core.MapEvent;
import com.hazelcast.core.Member;
public abstract class EntityManagement<E extends Entity> implements EntryListener<String, E>, InitializingBean {
protected final transient Logger logger = LoggerFactory.getLogger(getClass());
protected IMap<String, E> entityCache;
protected HazelcastInstance hzInstance;
//not sure I have to do this here
//protected Map<String, EntityManager<E>> mgrCache = new HashMap<String, EntityManager<E>>();
protected Map<String, EntityManager<E>> mgrCache = new HashMap<>();
@Autowired
protected AnnotationMBeanExporter mbeanExporter;
public EntityManagement(HazelcastInstance hzInstance) {
//super();
this.hzInstance = hzInstance;
}
@Override
public void afterPropertiesSet() throws Exception {
logger.trace("afterPropertiesSet.enter");
Set<String> names = entityCache.keySet();
for (String name: names) {
logger.trace("afterPropertiesSet; initiating entity: {}", name);
initEntityManager(name);
}
logger.trace("afterPropertiesSet.exit; initiated {} entity managers", names.size());
}
public void setEntityCache(IMap<String, E> entityCache) {
this.entityCache = entityCache;
this.entityCache.addEntryListener(this, false);
}
protected String getCurrentUser() {
return JMXUtils.getCurrentUser(((Member) hzInstance.getLocalEndpoint()).getStringAttribute(pn_cluster_login));
}
protected EntityManager<E> initEntityManager(String entityName) throws MalformedObjectNameException {
EntityManager<E> eMgr = null;
if (!mgrCache.containsKey(entityName)) {
eMgr = createEntityManager(entityName);
//eMgr.setEntityCache(entityCache);
mgrCache.put(entityName, eMgr);
mbeanExporter.registerManagedResource(eMgr, eMgr.getObjectName());
}
return eMgr;
}
protected abstract EntityManager<E> createEntityManager(String entityName);
public Collection<E> getEntities() {
return new ArrayList<E>(entityCache.values());
}
public EntityManager<E> getEntityManager(String entityName) {
return mgrCache.get(entityName);
}
protected String[] getEntityNames() {
Set<String> names = entityCache.keySet();
return names.toArray(new String[names.size()]);
}
protected TabularData getEntities(String name, String desc) {
Collection<E> entities = entityCache.values();
if (entities.size() == 0) {
return null;
}
TabularData result = null;
for (Entity entity: entities) {
try {
Map<String, Object> def = entity.convert();
CompositeData data = JMXUtils.mapToComposite(name, desc, def);
result = JMXUtils.compositeToTabular(name, desc, "name", result, data);
} catch (Exception ex) {
logger.error("getEntities; error", ex);
}
}
return result;
}
@Override
public void entryAdded(EntryEvent<String, E> event) {
logger.trace("entryAdded; event: {}", event);
String entityName = event.getKey();
try {
initEntityManager(entityName);
} catch (MBeanExportException | MalformedObjectNameException ex) {
// JMX registration failed.
logger.error("entryAdded.error: ", ex);
}
}
@Override
public void entryRemoved(EntryEvent<String, E> event) {
logger.trace("entryRemoved; event: {}", event);
String entityName = event.getKey();
EntityManager<E> eMgr = mgrCache.remove(entityName);
try {
mbeanExporter.unregisterManagedResource(eMgr.getObjectName());
} catch (MalformedObjectNameException ex) {
logger.error("entryRemoved.error: ", ex);
}
}
@Override
public void entryUpdated(EntryEvent<String, E> event) {
logger.trace("entryUpdated; event: {}", event);
}
@Override
public void entryEvicted(EntryEvent<String, E> event) {
logger.trace("entryEvicted; event: {}", event);
// make entity inactive ?
}
@Override
public void mapEvicted(MapEvent event) {
logger.trace("mapEvicted; event: {}", event);
// make entity inactive ?
}
@Override
public void mapCleared(MapEvent event) {
logger.trace("mapCleared; event: {}", event);
// shouldn't be this! delete all roles?
}
}