package scs.demos.mapreduce.schedule; import org.omg.CORBA.ORB; import org.omg.CORBA.Object; import org.omg.CORBA.SystemException; import org.omg.PortableServer.POA; import org.omg.PortableServer.POAHelper; import org.omg.PortableServer.POAManagerPackage.AdapterInactive; import org.omg.PortableServer.POAPackage.ServantNotActive; import org.omg.PortableServer.POAPackage.WrongPolicy; import org.omg.PortableServer.Servant; import scs.container.ComponentAlreadyLoaded; import scs.container.ComponentCollection; import scs.container.ComponentCollectionHelper; import scs.container.ComponentHandle; import scs.core.ComponentId; import scs.container.ComponentLoader; import scs.container.ComponentLoaderHelper; import scs.container.ComponentNotFound; import scs.container.LoadFailure; import scs.core.AlreadyConnected; import scs.core.ExceededConnectionLimit; import scs.core.IComponent; import scs.core.IComponentHelper; import scs.core.IReceptacles; import scs.core.IReceptaclesHelper; import scs.core.InvalidConnection; import scs.core.InvalidName; import scs.core.StartupFailed; import scs.core.ConnectionDescription; import scs.event_service.ChannelFactory; import scs.event_service.ChannelFactoryHelper; import scs.event_service.EventSink; import scs.event_service.EventSinkHelper; import scs.event_service.NameAlreadyInUse; import scs.event_service.servant.ConnectionStatus; import scs.event_service.servant.EventSinkConsumerServant; import scs.execution_node.ContainerAlreadyExists; import scs.execution_node.ExecutionNode; import scs.execution_node.ExecutionNodeHelper; import scs.execution_node.Property; import scs.demos.mapreduce.Worker; import scs.demos.mapreduce.WorkerHelper; import scs.demos.mapreduce.Task; import scs.demos.mapreduce.TaskStatus; import scs.demos.mapreduce.TaskHelper; import scs.demos.mapreduce.Reporter; import scs.demos.mapreduce.IOFormat; import scs.demos.mapreduce.IOFormatHelper; import scs.demos.mapreduce.IOFormatException; import scs.demos.mapreduce.FileSplit; import scs.demos.mapreduce.SplitException; import scs.demos.mapreduce.FileSplitHelper; import scs.demos.mapreduce.servant.TaskServant; import scs.execution_node.InvalidProperty; import java.util.Hashtable; import java.util.concurrent.LinkedBlockingQueue; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.*; /** * Objeto para inicializar os execution nodes, criando os containers e os * componentes workers * @author Sand Luz Correa */ public class WorkerInitializer { private String[] execNodeList; private MasterServant master; private ORB orb; private static final String EXEC_NODE_NAME = "ExecutionNode"; private static final String EXEC_NODE_FACET = "scs::execution_node::ExecutionNode"; private static final String SUFIX = ".txt"; private static final String MAP_REDUCE_CONTAINER = "MapReduceContainer"; private Hashtable hashNodes ; private DataInputStream in = null; private POA poa = null; private int[] mappers_p_nodes; private Reporter reporter = null; private String configFileName; private IOFormat ioformat = null; private String exception; private int mapped; private String nameServerHost = null; private String nameServerPort = null; private LinkedBlockingQueue<IComponent> workerComponentQueue; public WorkerInitializer(MasterServant master) throws Exception { try { this.master = master; this.orb = master.getOrb(); this.execNodeList = master.getExecNodeList(); this.reporter = master.getReporter(); this.configFileName = master.getConfigFileName(); this.mapped = 0; this.nameServerHost = master.getMasterHost(); this.nameServerPort = master.getMasterPort(); hashNodes = new Hashtable(); poa = POAHelper.narrow(orb.resolve_initial_references("RootPOA")); poa.the_POAManager().activate(); } catch (Exception e) { exception = LogError.getStackTrace(e); reporter.report(0, "WorkerInitializer::WorkerInitializer - Erro ao criar WorkerInializer. \n" + exception); throw e; } } /* Retorna um execution node dado o nome do host*/ private ExecutionNode getNode(String host) { try { InetAddress localAddr = InetAddress.getByName(host); String addrString = localAddr.toString(); String[] ipAddress = new String[2]; ipAddress = addrString.split("/"); String execName = EXEC_NODE_NAME + "-" + ipAddress[1]; String corbaname = "corbaname::" + nameServerHost + ":" + nameServerPort + "#" + execName; ExecutionNode execNode = null; reporter.report(1,"WorkerInitializer::getNode - Conectando ao execution node " + corbaname); org.omg.CORBA.Object obj = orb.string_to_object(corbaname); IComponent execNodeComp = IComponentHelper.narrow(obj); execNodeComp.startup(); Object ob = execNodeComp.getFacet(EXEC_NODE_FACET); execNode = ExecutionNodeHelper.narrow(ob); return execNode; } catch (SystemException ex) { exception = LogError.getStackTrace(ex); reporter.report(0,"WorkerInitializer::getNode - Erro ao conectar com o ExecutionNode " + host + ".\n" + exception); return null; } catch (StartupFailed e) { exception = LogError.getStackTrace(e); reporter.report(0,"WorkerInitializer::getNode - Startup do ExecutionNode " + host + " falhou. \n" + exception); return null; } catch (UnknownHostException e){ exception = LogError.getStackTrace(e); reporter.report(0,"WorkerInitializer::getNode - Erro convertendo nome de host para IP " + host + "\n" + exception); return null; } } /* Cria um container no execution node especificado */ private boolean createContainer(String name, ExecutionNode execNode) { try { Property prop = new Property(); prop.name = "language"; prop.value = "java"; Property propSeq[] = { prop }; IComponent container = execNode.startContainer(name, propSeq); if (container == null) { return false; } return true; } catch (ContainerAlreadyExists e) { reporter.report(0,"WorkerInitializer::createContainer - Ja existe um container com este nome:" + name); return false; } catch (InvalidProperty e) { reporter.report(0, "WorkerInitializer::createContainer - Erro ao setar propriedades do container"); return false; } } /* Cria um component no container associado a loader*/ private ComponentHandle createHandle(ComponentLoader loader, ComponentId compId){ ComponentHandle handle = null; try { handle = loader.load(compId, new String[] { "" }); handle.cmp.startup(); } catch (ComponentNotFound e) { reporter.report(0,"WorkerInitializer::createHandle - Componente " + compId.name + " nao encontrado."); } catch (ComponentAlreadyLoaded e) { reporter.report(0,"WorkerInitializer::createHandle - Componente " + compId.name + " j� foi criado."); } catch (LoadFailure e) { exception = LogError.getStackTrace(e); reporter.report(0,"WorkerInitializer::createHandle - Erro ao carregar componente " + compId.name + ".\n" + exception); } catch (StartupFailed e) { exception = LogError.getStackTrace(e); reporter.report(0,"WorkerInitializer::createHandle - Startup do componente " + compId.name + " falhou.\n" + exception); } return handle; } /* Instancia um servant IOFormatServant dado o nome da classe */ public IOFormat createIOFormatServant(String servantName) { IOFormat ioformat = null; try{ Servant obj = (Servant) Class.forName(servantName).newInstance(); ioformat = IOFormatHelper.narrow(this.poa.servant_to_reference(obj)); } catch (Exception e){ exception = LogError.getStackTrace(e); reporter.report(0,"WorkerInitializer::createIOFormatServant - Erro ao criar servant ioformat " + servantName + ".\n" + exception); } return ioformat; } /* Conecta aos execution nodes onde os workers serao criados */ public Hashtable connectToExecNodes(){ String port = master.getMasterPort(); for(int i = 0; i < execNodeList.length; i++){ ExecutionNode execNode = getNode(execNodeList[i]); if (execNode == null) return null; else hashNodes.put(execNodeList[i], execNode); } return hashNodes; } /* Cria um canal de evento para comunicacao entre master e workers */ public IComponent buildChannel(){ ExecutionNode execNode = getNode(master.getMasterHost()); if (execNode == null) return null; IComponent container = execNode.getContainer(master.getContainerName()); if (container == null){ reporter.report (0,"WorkerInitializer::builChannel - Erro ao retornar container do componente Master"); return null; } ComponentLoader loader = ComponentLoaderHelper.narrow(container .getFacet("scs::container::ComponentLoader")); if (loader == null) { reporter.report(0,"WorkerInitializer::buildChannel - Erro ao retornar loader do container master"); return null; } ComponentHandle handle = null; ComponentId newComponent = new ComponentId(); newComponent.name = "EventManager"; newComponent.version = 1; handle = createHandle(loader, newComponent); if (handle == null) { return null; } IComponent eventMgr = handle.cmp; ChannelFactory chFactory = ChannelFactoryHelper.narrow(eventMgr.getFacet("scs::event_service::ChannelFactory")); if( chFactory== null ) { reporter.report(0,"WorkerInitializer::buildChannel - Erro ao retornar ChannelFactory !"); return null; } /* Cria o eventSink para se conectar ao canal de evento*/ ConnectionStatus connStatus = null; EventSinkConsumerServant servant = null; org.omg.CORBA.Object servantObj = null; IComponent masterChannel = null; try { connStatus = new ConnectionStatus(false); servant = new EventSinkMaster(connStatus,master); servantObj = this.poa.servant_to_reference(servant); EventSink eventSink = EventSinkHelper.narrow(servantObj); if (eventSink == null){ reporter.report(0,"WorkerInitializer::buildChannel - Erro ao retornar eventSink"); return null; } masterChannel = chFactory.create("MasterChannel"); masterChannel.startup(); IReceptacles evSource = IReceptaclesHelper.narrow(masterChannel.getFacet("scs::core::IReceptacles")); /* Registra o eventsink no channel selecionado */ int connID=0; connID = evSource.connect("EventSource", eventSink); connStatus.setConnected(true); return masterChannel; } catch (Exception e) { exception = LogError.getStackTrace(e); reporter.report(0,"WorkerInitializer::buildChannel - Erro ao instanciar channel.\n" + exception); return null; } } /* Constroi a lista de Workers */ public LinkedBlockingQueue buildWorkerQueue() { IComponent workerComponent; String containerName; LinkedBlockingQueue<Worker> workerQueue = new LinkedBlockingQueue<Worker>(); workerComponentQueue = new LinkedBlockingQueue<IComponent>(); ComponentId workerCompId = new ComponentId(); workerCompId.name = "Worker"; workerCompId.version = 1; ComponentHandle handle = null; reporter.report(1, "WorkerInitializer::buildWorkerQueue - Comecando balanceamento de carga"); /* * Balanceamento de carga entre os nos. * Calcula o numero de mapper por no */ int remainder = master.getNum_Mappers() % execNodeList.length; mappers_p_nodes = new int[execNodeList.length]; for (int i = 0; i < execNodeList.length; i++) { if (i < remainder) mappers_p_nodes[i] = master.getNum_Mappers() / execNodeList.length + 1; else mappers_p_nodes[i] = master.getNum_Mappers() / execNodeList.length; reporter.report(1,"WorkerInitializer::buildWorkerQueue - mappers_p_nodes[i]= " + mappers_p_nodes[i]); } /* Criacao dos workers */ for(int i = 0; i < execNodeList.length; i++){ ExecutionNode execNode = (ExecutionNode) hashNodes.get(execNodeList[i]); for (int j = 0; j < mappers_p_nodes[i] ; j++){ containerName = MAP_REDUCE_CONTAINER + j; if (!this.createContainer(containerName, execNode)) { reporter.report(0,"WorkerInitializer::buildWorkerQueue - Erro criando o container " + containerName); return null; } IComponent container; container = execNode.getContainer(containerName); try { container.startup(); } catch (StartupFailed e) { exception = LogError.getStackTrace(e); reporter.report(0,"WorkerInitializer::buildWorkerQueue - Erro no startup do container " + containerName + ".\n" + exception); return null; } ComponentLoader loader = ComponentLoaderHelper.narrow(container .getFacet("scs::container::ComponentLoader")); if (loader == null) { reporter.report(0,"WorkerInitializer::buildWorkerQueue - Erro retornando componentLoader" + " de workers"); return null; } handle = createHandle(loader, workerCompId); if (handle == null) return null; workerComponent = handle.cmp; Worker w = WorkerHelper.narrow(workerComponent.getFacetByName("Worker")); if(!w.start(configFileName, execNodeList[i], master.getChannel(), reporter, workerComponent)) { reporter.report(0,"WorkerInitializer::buildWorkerQueue - Erro chamando start de worker"); return null; } workerComponentQueue.add(workerComponent); workerQueue.add(w); } } return workerQueue; } public LinkedBlockingQueue<IComponent> buildWorkerComponentQueue(){ return this.workerComponentQueue; } /* Constroi uma lista de tarefas map */ public LinkedBlockingQueue buildTaskQueue () { try { LinkedBlockingQueue<Task> taskQueue = new LinkedBlockingQueue<Task>(); ioformat = master.getIOFormat(); FileSplit[] splits = ioformat.getSplits(configFileName, reporter); for(int i=0; i<splits.length; i++) { FileSplit[] inputFileSplit = new FileSplit[1]; inputFileSplit[0] = splits[i]; Task t = TaskHelper.narrow(this.poa.servant_to_reference( new TaskServant(TaskStatus.MAP, inputFileSplit, 0))); taskQueue.add(t); } return taskQueue; } catch (Exception e) { exception = LogError.getStackTrace(e); reporter.report(0,"WorkerInitializer::buildTask - Erro ao retornar particoes do arquivo.\n" + exception); return null; } } /* destroi os containers mapreduce criados */ public void finish() { try{ String containerName; for(int i = 0; i < execNodeList.length; i++){ ExecutionNode execNode = (ExecutionNode) hashNodes.get(execNodeList[i]); reporter.report(1,"WorkerInitializer::finish - Finalizando containers MAPREDUCE"); for (int j = 0; j < mappers_p_nodes[i] ; j++){ containerName = MAP_REDUCE_CONTAINER + j; execNode.stopContainer(containerName); } } } catch (Exception e){ exception = LogError.getStackTrace(e); reporter.report(0,"WorkerInitializer::finish - Erro ao finalizar containers.\n" + exception); return; } } }