package com.neverwinterdp.scribengin.ScribeConsumerManager; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.apache.log4j.Logger; import com.neverwinterdp.scribengin.cluster.ScribeConsumerStatusCommand; import com.neverwinterdp.scribengin.scribeconsumer.ScribeConsumerConfig; import com.neverwinterdp.server.Server; import com.neverwinterdp.server.ServerRegistration; import com.neverwinterdp.server.cluster.ClusterMember; import com.neverwinterdp.server.cluster.hazelcast.HazelcastClusterClient; import com.neverwinterdp.server.command.ServiceCommand; import com.neverwinterdp.server.command.ServiceCommandResult; import com.neverwinterdp.server.service.ServiceRegistration; import com.neverwinterdp.server.shell.Shell; public class ClusterScribeConsumerManager extends AbstractScribeConsumerManager{ private static final Logger LOG = Logger.getLogger(ClusterScribeConsumerManager.class.getName()); //List<ServerInfo> servers = new LinkedList<ServerInfo>(); List<ServerInfo> servers = Collections.synchronizedList(new LinkedList<ServerInfo>()); private class ServerInfo{ public Server server; public ScribeConsumerConfig conf; public ServerInfo(Server s, ScribeConsumerConfig c){ this.server = s; this.conf = c; } } public ClusterScribeConsumerManager(){ } @Override public boolean startNewConsumers(ScribeConsumerConfig c, List<String> topics) { boolean retVal = true; for(String t: topics){ c.topic = t; if(!this.startNewConsumer(new ScribeConsumerConfig(c))){ retVal = false; } } return retVal; } @Override public boolean startNewConsumer(ScribeConsumerConfig c) { Server scribeConsumer = Server.create("-Pserver.name=scribemaster", "-Pserver.roles=scribeconsumer"); Shell shell = new Shell() ; shell.getShellContext().connect(); String installScript ="module install " + " -Pmodule.data.drop=true" + " -Pscribeconsumer:precommitpathprefix=" + c.PRE_COMMIT_PATH_PREFIX + " -Pscribeconsumer:commitpathprefix=" + c.COMMIT_PATH_PREFIX + " -Pscribeconsumer:topic="+ c.topic + " -Pscribeconsumer:partition=" + Integer.toString(c.partition) + " -Pscribeconsumer:brokerList=" + c.getBrokerListAsString() + " -Pscribeconsumer:commitCheckPointInterval="+ Long.toString(c.commitCheckPointInterval); if(c.hdfsPath != null){ installScript += " -Pscribeconsumer:hdfsPath="+c.hdfsPath; } if(c.cleanStart){ installScript += " -Pscribeconsumer:cleanStart=True"; } if(c.date_partitioner != null){ installScript += " -Pscribeconsumer:date_partitioner="+c.date_partitioner; } installScript += " --member-role scribeconsumer --autostart --module ScribeConsumer \n"; shell.executeScript(installScript); servers.add(new ServerInfo(scribeConsumer, c)); return true; } @Override public void monitorConsumers() { HazelcastClusterClient client = new HazelcastClusterClient() ; List<ScribeConsumerConfig> toAdd = new LinkedList<ScribeConsumerConfig>(); synchronized(servers){ Iterator<ServerInfo> it = servers.iterator(); while (it.hasNext()) { ServerInfo si = it.next(); ClusterMember member = si.server.getClusterService().getMember(); ServerRegistration serverRegistration = client.getServerRegistration(member); ServiceRegistration statusService = serverRegistration.getServices().get(0) ; ServiceCommand<Thread.State> serverState = new ScribeConsumerStatusCommand().setLogEnable(true) ; serverState.setTargetService(statusService); ServiceCommandResult<Thread.State> serverThreadState = client.execute(serverState, member) ; if(serverThreadState.hasError()) { LOG.error("Error getting thread state: "+serverThreadState.getError()); continue; } Thread.State state = serverThreadState.getResult(); //Basically ScribeConsumer should never die, so restart it if something happens if(!(state == Thread.State.NEW || state == Thread.State.RUNNABLE) || state == null){ LOG.error("Server in bad state. Thread state: "+state.toString()+" Topic: "+si.conf.topic); si.conf.cleanStart = false; toAdd.add(new ScribeConsumerConfig(si.conf)); si.server.shutdown(); si.server.destroy(); it.remove(); } else { System.err.println("SERVER STATE: "+state.toString()); } } } for(ScribeConsumerConfig c: toAdd){ startNewConsumer(c); } } @Override public boolean shutdownConsumers() { boolean retVal = true; synchronized(servers){ Iterator<ServerInfo> iterator = servers.iterator(); while(iterator.hasNext()){ ServerInfo si = iterator.next(); try{ si.server.shutdown(); si.server.destroy(); iterator.remove(); } catch(Exception e){ e.printStackTrace(); retVal = false; } } } return retVal; } @Override public int getNumConsumers() { synchronized(servers){ return servers.size(); } } @Override public boolean killConsumersUncleanly() { boolean retVal = true; Iterator<ServerInfo> iterator = servers.iterator(); synchronized(servers){ while(iterator.hasNext()){ ServerInfo si = iterator.next(); try{ si.server.shutdown(); si.server.destroy(); } catch(Exception e){ e.printStackTrace(); retVal = false; } } return retVal; } } }