/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.wordpress.salaboy; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.drools.SystemEventListenerFactory; import org.drools.grid.ConnectionFactoryService; import org.drools.grid.Grid; import org.drools.grid.GridConnection; import org.drools.grid.GridNode; import org.drools.grid.GridServiceDescription; import org.drools.grid.SocketService; import org.drools.grid.conf.GridPeerServiceConfiguration; import org.drools.grid.conf.impl.GridPeerConfiguration; import org.drools.grid.impl.GridImpl; import org.drools.grid.impl.MultiplexSocketServerImpl; import org.drools.grid.io.impl.MultiplexSocketServiceCongifuration; import org.drools.grid.remote.mina.MinaAcceptorFactoryService; import org.drools.grid.service.directory.WhitePages; import org.drools.grid.service.directory.impl.CoreServicesLookupConfiguration; import org.drools.grid.service.directory.impl.WhitePagesLocalConfiguration; import org.drools.grid.timer.impl.CoreServicesSchedulerConfiguration; import org.neo4j.kernel.AbstractGraphDatabase; import org.neo4j.server.WrappingNeoServerBootstrapper; import org.neo4j.server.configuration.Configurator; import org.neo4j.server.configuration.EmbeddedServerConfigurator; import org.neo4j.test.ImpermanentGraphDatabase; import com.wordpress.salaboy.context.tracking.ContextTrackingProvider; import com.wordpress.salaboy.context.tracking.ContextTrackingService; import com.wordpress.salaboy.messaging.MessageConsumerWorker; import com.wordpress.salaboy.messaging.MessageConsumerWorkerHandler; import com.wordpress.salaboy.messaging.MessageServerSingleton; import com.wordpress.salaboy.model.*; import com.wordpress.salaboy.model.events.*; import com.wordpress.salaboy.model.messages.*; import com.wordpress.salaboy.model.messages.patient.HeartBeatMessage; import com.wordpress.salaboy.model.persistence.PersistenceService; import com.wordpress.salaboy.model.persistence.PersistenceServiceProvider; import com.wordpress.salaboy.services.*; import com.wordpress.salaboy.services.util.MessageToEventConverter; /** * @author salaboy * @author esteban */ public class CoreServer { private static PersistenceService persistenceService; private static ContextTrackingService trackingService; protected Map<String, GridServiceDescription> coreServicesMap = new HashMap<String, GridServiceDescription>(); protected static Grid grid; protected static GridNode remoteN1; private Map<String,Boolean> vehicleHitEmergency = new HashMap<String, Boolean> (); private Map<String,Boolean> vehicleHitHospital = new HashMap<String, Boolean> (); //CurrentWorkers private MessageConsumerWorker reportingWorker; private MessageConsumerWorker heartBeatReceivedWorker; private MessageConsumerWorker vehicleDispatchedWorker; private MessageConsumerWorker vehicleHitsHospitalWorker; private MessageConsumerWorker vehicleHitsFireDepartmentWorker; private MessageConsumerWorker vehicleHitsEmergencyWorker; private MessageConsumerWorker emergencyDetailsPersistenceWorker; private MessageConsumerWorker selectedProcedureWorker; private MessageConsumerWorker phoneCallsWorker; private MessageConsumerWorker asynchProcedureStartWorker; private MessageConsumerWorker procedureEndedWorker; private MessageConsumerWorker allProceduresEndedWorker; private MessageConsumerWorker fireTruckDecreaseWaterLevelWorker; private MessageConsumerWorker fireTruckOutOfWaterWorker; private MessageConsumerWorker fireTruckWaterRefillMonitorWorker; private static boolean startWrappingServer = true; private static final String SERVER_API_PATH_PROP = ContextTrackingProvider.SERVER_BASE_URL + "/db/data/"; private static AbstractGraphDatabase myDb; private static WrappingNeoServerBootstrapper srv; public static void main(String[] args) throws Exception { if (startWrappingServer) { myDb = new ImpermanentGraphDatabase(); EmbeddedServerConfigurator config = new EmbeddedServerConfigurator( myDb); config.configuration().setProperty( Configurator.WEBSERVER_PORT_PROPERTY_KEY, 7575); config.configuration().setProperty( Configurator.REST_API_PATH_PROPERTY_KEY, SERVER_API_PATH_PROP); srv = new WrappingNeoServerBootstrapper(myDb, config); srv.start(); } final CoreServer coreServer = new CoreServer(); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { try { System.out.println("Stopping Core Server ... "); MessageServerSingleton.getInstance().stop(); remoteN1.dispose(); grid.get(SocketService.class).close(); HumanTaskServerService.getInstance().stopTaskServer(); System.out.println("Core Server Stopped! "); coreServer.stopWorkers(); if (srv != null) { srv.stop(); } } catch (Exception ex) { System.out.println("Something goes wrong with the shutdown! ->"+ex.getMessage()); Logger.getLogger(CoreServer.class.getName()).log(Level.SEVERE, null, ex); } } }); // Map<String, Object> params = new HashMap<String, Object>(); // params.put("ContextTrackingImplementation", ContextTrackingProvider.ContextTrackingServiceType.IN_MEMORY); // PersistenceServiceConfiguration conf = new PersistenceServiceConfiguration(params); // persistenceService = PersistenceServiceProvider.getPersistenceService(PersistenceServiceProvider.PersistenceServiceType.DISTRIBUTED_MAP, conf); // // trackingService = ContextTrackingProvider.getTrackingService((ContextTrackingProvider.ContextTrackingServiceType) conf.getParameters().get("ContextTrackingImplementation")); persistenceService = PersistenceServiceProvider.getPersistenceService(); trackingService = ContextTrackingProvider.getTrackingService(); coreServer.startServer(); } public void startServer() throws Exception { MessageServerSingleton.getInstance().start(); //Starting Grid View createRemoteNode(); //Starting Human Task Server HumanTaskServerService.getInstance().initTaskServer(); //Init Persistence Service and add all the city entities for (Vehicle vehicle : CityEntities.vehicles) { System.out.println("Initializing Vehicle into the Cache - >" + vehicle); persistenceService.storeVehicle(vehicle); } for (Hospital hospital : CityEntities.hospitals) { System.out.println("Initializing Hospital into the Cache - >" + hospital); persistenceService.storeHospital(hospital); } FirefightersDepartment firefightersDepartment = (FirefightersDepartment)CityEntities.buildings.get("Firefighters Department"); System.out.println("Initializing Hospital into the Cache - >" + firefightersDepartment); persistenceService.storeFirefightersDepartment(firefightersDepartment); //Init First Response Service, just to have one instance ready for new phone calls GenericEmergencyProcedureImpl.getInstance(); //Start Workers startQueuesWorkers(); } private void startQueuesWorkers() { try { //Phone Calls Worker phoneCallsWorker = new MessageConsumerWorker("IncomingCallCoreServer", new MessageConsumerWorkerHandler<IncomingCallMessage>() { @Override public void handleMessage(IncomingCallMessage incomingCallMessage) { GenericEmergencyProcedureImpl.getInstance().newPhoneCall(incomingCallMessage.getCall()); } }); //Procedure Ended Worker procedureEndedWorker = new MessageConsumerWorker("ProcedureEndedCoreServer", new MessageConsumerWorkerHandler<ProcedureCompletedMessage>() { @Override public void handleMessage(ProcedureCompletedMessage procedureEndsMessage) { GenericEmergencyProcedureImpl.getInstance().procedureCompletedNotification(procedureEndsMessage.getEmergencyId(), procedureEndsMessage.getProcedureId()); } }); //All Procedures Ended Worker allProceduresEndedWorker = new MessageConsumerWorker("AllProceduresEndedCoreServer", new MessageConsumerWorkerHandler<AllProceduresEndedMessage>() { @Override public void handleMessage(AllProceduresEndedMessage allProceduresEndedMessage) { GenericEmergencyProcedureImpl.getInstance().allProceduresEnededNotification(new AllProceduresEndedEvent(allProceduresEndedMessage.getEmergencyId(), allProceduresEndedMessage.getEndedProcedures())); } }); //Procedure Selected Worker //@TODO: Delete because now the generic procedure use the Start Procedure work item to do this selectedProcedureWorker = new MessageConsumerWorker("selectedProcedureCoreServer", new MessageConsumerWorkerHandler<SelectedProcedureMessage>() { @Override public void handleMessage(SelectedProcedureMessage selectedProcedureMessage) { try { ProceduresMGMTService.getInstance().newRequestedProcedure(selectedProcedureMessage.getEmergencyId(), selectedProcedureMessage.getProcedureName(), selectedProcedureMessage.getParameters()); } catch (IOException ex) { Logger.getLogger(CoreServer.class.getName()).log(Level.SEVERE, null, ex); } } }); //Emergency Details Persistence Selected Worker emergencyDetailsPersistenceWorker = new MessageConsumerWorker("emergencyDetailsCoreServer", new MessageConsumerWorkerHandler<EmergencyDetailsMessage>() { @Override public void handleMessage(EmergencyDetailsMessage emergencyDetailsMessage) { //update the emergency persistenceService.storeEmergency(emergencyDetailsMessage.getEmergency()); //attachs it to the call trackingService.attachEmergency(emergencyDetailsMessage.getEmergency().getCall().getId(), emergencyDetailsMessage.getEmergency().getId()); } }); //Vehicle Hits an Emergency Selected Worker vehicleHitsEmergencyWorker = new MessageConsumerWorker("vehicleHitsEmergencyCoreServer", new MessageConsumerWorkerHandler<VehicleHitsEmergencyMessage>() { @Override public void handleMessage(VehicleHitsEmergencyMessage vehicleHitsEmergencyMessage) { EmergencyEvent event = MessageToEventConverter.convertMessageToEvent(vehicleHitsEmergencyMessage); vehicleHitEmergency.put(vehicleHitsEmergencyMessage.getVehicleId(), Boolean.TRUE); ProceduresMGMTService.getInstance().notifyProcedures(event); } }); //Vehicle Hits an Hospital Selected Worker vehicleHitsHospitalWorker = new MessageConsumerWorker("vehicleHitsHospitalCoreServer", new MessageConsumerWorkerHandler<VehicleHitsHospitalMessage>() { @Override public void handleMessage(VehicleHitsHospitalMessage vehicleHitsHospitalMessage) { EmergencyEvent event = MessageToEventConverter.convertMessageToEvent(vehicleHitsHospitalMessage); vehicleHitHospital.put(vehicleHitsHospitalMessage.getVehicleId(), Boolean.TRUE); ProceduresMGMTService.getInstance().notifyProcedures(event); //Notify VehicleMGMTService VehiclesMGMTService.getInstance().vehicleRemoved(vehicleHitsHospitalMessage.getVehicleId()); } }); //Vehicle Hits a Fire Department Selected Worker vehicleHitsFireDepartmentWorker = new MessageConsumerWorker("vehicleHitsFireDepartmentWorkerCoreServer", new MessageConsumerWorkerHandler<VehicleHitsFireDepartmentMessage>() { @Override public void handleMessage(VehicleHitsFireDepartmentMessage vehicleHitsFireDepartmentMessage) { EmergencyEvent event = MessageToEventConverter.convertMessageToEvent(vehicleHitsFireDepartmentMessage); ProceduresMGMTService.getInstance().notifyProcedures(event); VehiclesMGMTService.getInstance().processEvent((EmergencyVehicleEvent)event); } }); //Vehicle Dispatched vehicleDispatchedWorker = new MessageConsumerWorker("vehicleDispatchedCoreServer", new MessageConsumerWorkerHandler<VehicleDispatchedMessage>() { @Override public void handleMessage(VehicleDispatchedMessage message) { vehicleHitEmergency.put(message.getVehicleId(), Boolean.FALSE); vehicleHitHospital.put(message.getVehicleId(), Boolean.FALSE); VehiclesMGMTService.getInstance().newVehicleDispatched(message.getEmergencyId(), message.getVehicleId()); // try { // Thread.sleep(3000); // } catch (InterruptedException ex) { // Logger.getLogger(CoreServer.class.getName()).log(Level.SEVERE, null, ex); // } } }); //Heart Beat Received heartBeatReceivedWorker = new MessageConsumerWorker("heartBeatCoreServer", new MessageConsumerWorkerHandler<HeartBeatMessage>() { @Override public void handleMessage(HeartBeatMessage message) { //Only notify if the vehicle already hit the emergency //but it doesnt hit the hospital Boolean hitEmergency = vehicleHitEmergency.get(message.getVehicleId()); Boolean hitHospital = vehicleHitHospital.get(message.getVehicleId()); if (hitEmergency == null || hitHospital == null){ return; } if (hitEmergency && !hitHospital){ EmergencyEvent event = MessageToEventConverter.convertMessageToEvent(message); VehiclesMGMTService.getInstance().processEvent((PulseEvent)event); } } }); //FireTruck Water Level Decreased Received fireTruckDecreaseWaterLevelWorker = new MessageConsumerWorker("fireTruckDecreaseWaterLevelCoreServer", new MessageConsumerWorkerHandler<FireTruckDecreaseWaterLevelMessage>() { @Override public void handleMessage(FireTruckDecreaseWaterLevelMessage message) { VehiclesMGMTService.getInstance().processEvent(new FireTruckDecreaseWaterLevelEvent(message.getEmergencyId(), message.getVehicleId(), message.getTime())); } }); //FireTruck Out Of Water Received fireTruckOutOfWaterWorker = new MessageConsumerWorker("fireTruckOutOfWaterCoreServer", new MessageConsumerWorkerHandler<FireTruckOutOfWaterMessage>() { @Override public void handleMessage(FireTruckOutOfWaterMessage message) { EmergencyEvent event = MessageToEventConverter.convertMessageToEvent(message); VehiclesMGMTService.getInstance().processEvent((EmergencyVehicleEvent)event); ProceduresMGMTService.getInstance().notifyProcedures(event); } }); reportingWorker = new MessageConsumerWorker("reportingCoreServer", new MessageConsumerWorkerHandler<EmergencyInterchangeMessage>() { @Override public void handleMessage(EmergencyInterchangeMessage message) { persistenceService.addEntryToReport(message.getEmergencyId(), message.toString()); } }); asynchProcedureStartWorker = new MessageConsumerWorker("asyncProcedureStartCoreServer", new MessageConsumerWorkerHandler<AsyncProcedureStartMessage>() { @Override public void handleMessage(AsyncProcedureStartMessage message) { System.out.println(">>>>>>>>>>>Creating a new Procedure = "+message.getProcedureName()); try { ProceduresMGMTService.getInstance().newRequestedProcedure(message.getEmergencyId(), message.getProcedureName(), message.getParameters()); } catch (IOException ex) { Logger.getLogger(CoreServer.class.getName()).log(Level.SEVERE, null, ex); } } }); fireTruckWaterRefillMonitorWorker = new MessageConsumerWorker("asynchFireMonitorCoreServer", new MessageConsumerWorkerHandler<FireTruckWaterRefilledMessage>() { @Override public void handleMessage(FireTruckWaterRefilledMessage message) { VehiclesMGMTService.getInstance().processEvent((EmergencyVehicleEvent)MessageToEventConverter.convertMessageToEvent(message)); } }); fireTruckWaterRefillMonitorWorker.start(); reportingWorker.start(); heartBeatReceivedWorker.start(); vehicleDispatchedWorker.start(); vehicleHitsEmergencyWorker.start(); vehicleHitsHospitalWorker.start(); emergencyDetailsPersistenceWorker.start(); selectedProcedureWorker.start(); phoneCallsWorker.start(); asynchProcedureStartWorker.start(); procedureEndedWorker.start(); allProceduresEndedWorker.start(); fireTruckDecreaseWaterLevelWorker.start(); fireTruckOutOfWaterWorker.start(); vehicleHitsFireDepartmentWorker.start(); phoneCallsWorker.join(); } catch (InterruptedException ex) { Logger.getLogger(CoreServer.class.getName()).log(Level.SEVERE, null, ex); } } private void stopWorkers() { if(reportingWorker != null ){ reportingWorker.stopWorker(); } if(heartBeatReceivedWorker != null){ heartBeatReceivedWorker.stopWorker(); } if(vehicleDispatchedWorker!= null){ vehicleDispatchedWorker.stopWorker(); } if(vehicleHitsEmergencyWorker != null){ vehicleHitsEmergencyWorker.stopWorker(); } if(vehicleHitsHospitalWorker != null){ vehicleHitsHospitalWorker.stopWorker(); } if(emergencyDetailsPersistenceWorker != null){ emergencyDetailsPersistenceWorker.stopWorker(); } if(selectedProcedureWorker != null){ selectedProcedureWorker.stopWorker(); } if(asynchProcedureStartWorker != null){ asynchProcedureStartWorker.stopWorker(); } if(phoneCallsWorker != null){ phoneCallsWorker.stopWorker(); } if(procedureEndedWorker != null){ procedureEndedWorker.stopWorker(); } if(allProceduresEndedWorker != null){ allProceduresEndedWorker.stopWorker(); } if(fireTruckDecreaseWaterLevelWorker != null){ fireTruckDecreaseWaterLevelWorker.stopWorker(); } if(fireTruckOutOfWaterWorker != null){ fireTruckOutOfWaterWorker.stopWorker(); } if(vehicleHitsFireDepartmentWorker != null){ vehicleHitsFireDepartmentWorker.stopWorker(); } } protected void createRemoteNode() { grid = new GridImpl(new HashMap<String, Object>()); configureGrid1(grid, 8000, null); GridNode n1 = grid.createGridNode("n1"); grid.get(SocketService.class).addService("n1", 8000, n1); GridServiceDescription<GridNode> n1Gsd = grid.get(WhitePages.class).lookup("n1"); GridConnection<GridNode> conn = grid.get(ConnectionFactoryService.class).createConnection(n1Gsd); remoteN1 = conn.connect(); } private void configureGrid1(Grid grid, int port, WhitePages wp) { //Local Grid Configuration, for our client GridPeerConfiguration conf = new GridPeerConfiguration(); //Configuring the Core Services White Pages GridPeerServiceConfiguration coreSeviceWPConf = new CoreServicesLookupConfiguration(coreServicesMap); conf.addConfiguration(coreSeviceWPConf); //Configuring the Core Services Scheduler GridPeerServiceConfiguration coreSeviceSchedulerConf = new CoreServicesSchedulerConfiguration(); conf.addConfiguration(coreSeviceSchedulerConf); //Configuring the WhitePages WhitePagesLocalConfiguration wplConf = new WhitePagesLocalConfiguration(); wplConf.setWhitePages(wp); conf.addConfiguration(wplConf); if (port >= 0) { //Configuring the SocketService MultiplexSocketServiceCongifuration socketConf = new MultiplexSocketServiceCongifuration(new MultiplexSocketServerImpl("127.0.0.1", new MinaAcceptorFactoryService(), SystemEventListenerFactory.getSystemEventListener(), grid)); socketConf.addService(WhitePages.class.getName(), wplConf.getWhitePages(), port); conf.addConfiguration(socketConf); } conf.configure(grid); } }