package com.bagri.client.hazelcast.impl;
import static com.bagri.core.server.api.CacheConstants.TPN_XDM_HEALTH;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.bagri.core.api.HealthChangeListener;
import com.bagri.core.api.HealthCheckState;
import com.bagri.core.api.HealthManagement;
import com.bagri.core.api.HealthState;
import com.bagri.core.api.BagriException;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.ITopic;
import com.hazelcast.core.Message;
import com.hazelcast.core.MessageListener;
public class HealthManagementImpl implements HealthManagement, MessageListener<HealthState> {
private final static Logger logger = LoggerFactory.getLogger(HealthManagementImpl.class);
private HazelcastInstance hzInstance;
private HealthState state = HealthState.good;
private HealthCheckState checkState = HealthCheckState.log;
private Map<Integer, HealthChangeListener> listeners = new HashMap<>();
public HealthManagementImpl() {
super();
}
public HealthManagementImpl(HazelcastInstance hzInstance) {
this.hzInstance = hzInstance;
ITopic<HealthState> hTopic = hzInstance.getTopic(TPN_XDM_HEALTH);
hTopic.addMessageListener(this);
// TODO: get initial state somehow!
}
public void checkClusterState() throws BagriException {
if (checkState != HealthCheckState.skip) {
if (!isClusterSafe()) {
if (checkState == HealthCheckState.raise) {
throw new BagriException("System is not healthy", BagriException.ecHealth);
} else {
// log unhealthy time here?
logger.warn("System is not healthy");
}
}
}
}
@Override
public boolean isClusterSafe() {
return state == HealthState.good;
}
@Override
public int getClusterSize() {
return hzInstance.getCluster().getMembers().size();
}
@Override
public HealthState getHealthState() {
return state;
}
public HealthCheckState getCheckState() {
return checkState;
}
public void setCheckSate(HealthCheckState state) {
this.checkState = state;
}
@Override
public void addHealthChangeListener(HealthChangeListener listener) {
listeners.put(listener.hashCode(), listener);
}
@Override
public void removeHealthChangeListener(HealthChangeListener listener) {
listeners.remove(listener.hashCode());
}
@Override
public void onMessage(Message<HealthState> message) {
HealthState newState = message.getMessageObject();
if (state != newState) {
for (HealthChangeListener list: listeners.values()) {
list.onHealthStateChange(newState);
}
logger.trace("onMessage; health state changed from {} to {}; listeners notified: {}",
state, newState, listeners.size());
}
state = newState;
}
}