/* * To change this template, choose Tools | Templates and open the template in * the editor. */ package com.wordpress.salaboy.context.tracking; import java.util.UUID; import org.neo4j.cypher.ExecutionEngine; import org.neo4j.cypher.ExecutionResult; import org.neo4j.cypher.commands.Query; import org.neo4j.cypher.javacompat.CypherParser; import org.neo4j.graphdb.*; import org.neo4j.graphdb.index.Index; import org.neo4j.graphdb.index.IndexManager; import scala.collection.Iterator; /** * * @author salaboy */ public class ContextTrackingServiceImpl implements ContextTrackingService { private GraphDatabaseService graphDb; private IndexManager index; private Index<Node> callsIndex; private Index<Node> emergenciesIndex; private Index<Node> proceduresIndex; private Index<Node> vehiclesIndex; private Index<Node> channelsIndex; private Index<Node> buildingsIndex; private Index<Node> patientsIndex; public GraphDatabaseService getGraphDb() { return graphDb; } public ContextTrackingServiceImpl(GraphDatabaseService graphDb) { this.graphDb = graphDb; this.index = this.graphDb.index(); this.callsIndex = index.forNodes("calls"); this.emergenciesIndex = index.forNodes("emergencies"); this.proceduresIndex = index.forNodes("procedures"); this.vehiclesIndex = index.forNodes("vehicles"); this.channelsIndex = index.forNodes("channels"); this.buildingsIndex = index.forNodes("buildings"); this.patientsIndex = index.forNodes("patients"); } @Override public String newCallId() { Transaction tx = graphDb.beginTx(); String callId = "Call-" + UUID.randomUUID().toString(); try { Node callNode = graphDb.createNode(); callNode.setProperty("callId", callId); callNode.setProperty("name", callId); //??? DO I REALLY NEED THIS?? this.callsIndex.add(callNode, "callId", callId); tx.success(); } finally { tx.finish(); } return callId; } @Override public String newEmergencyId() { Transaction tx = graphDb.beginTx(); String emergencyId = "Emergency-" + UUID.randomUUID().toString(); try { Node emergencyNode = graphDb.createNode(); emergencyNode.setProperty("emergencyId", emergencyId); emergencyNode.setProperty("name", emergencyId); this.emergenciesIndex.add(emergencyNode, "emergencyId", emergencyId); tx.success(); } finally { tx.finish(); } return emergencyId; } @Override public String newEmergencyEntityBuildingId() { Transaction tx = graphDb.beginTx(); String buildingId = "EntityBuilding-" + UUID.randomUUID().toString(); try { Node buildingNode = graphDb.createNode(); buildingNode.setProperty("buildingId", buildingId); buildingNode.setProperty("name", buildingId); this.buildingsIndex.add(buildingNode, "buildingId", buildingId); tx.success(); } finally { tx.finish(); } return buildingId; } @Override public String newPatientId() { Transaction tx = graphDb.beginTx(); String patientId = "Patient-" + UUID.randomUUID().toString(); try { Node patientNode = graphDb.createNode(); patientNode.setProperty("patientId", patientId); patientNode.setProperty("name", patientId); this.patientsIndex.add(patientNode, "patientId", patientId); tx.success(); } finally { tx.finish(); } return patientId; } @Override public void attachEmergency(String callId, String emergencyId) { Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start n=(calls, 'callId:" + callId + "') return n"); ExecutionResult result = engine.execute(query); Iterator<Node> n_column = result.columnAs("n"); Node call = n_column.next(); query = parser.parse("start n=(emergencies, 'emergencyId:" + emergencyId + "') return n"); result = engine.execute(query); n_column = result.columnAs("n"); Node emergency = n_column.next(); call.createRelationshipTo(emergency, EmergencyRelationshipType.CREATES); tx.success(); } finally { tx.finish(); } } @Override public String newProcedureId() { Transaction tx = graphDb.beginTx(); String procedureId = "Procedure-" + UUID.randomUUID().toString(); try { Node procedureNode = graphDb.createNode(); procedureNode.setProperty("procedureId", procedureId); procedureNode.setProperty("name", procedureId); this.proceduresIndex.add(procedureNode, "procedureId", procedureId); tx.success(); } finally { tx.finish(); } return procedureId; } @Override public void attachProcedure(String emergencyId, String procedureId) { System.out.println(">>>> Attaching Procedure " + procedureId + " to Emergency " + emergencyId); Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start n=(emergencies, 'emergencyId:" + emergencyId + "') return n"); ExecutionResult result = engine.execute(query); Iterator<Node> n_column = result.columnAs("n"); Node emergency = n_column.next(); query = parser.parse("start n=(procedures, 'procedureId:" + procedureId + "') return n"); result = engine.execute(query); n_column = result.columnAs("n"); Node procedure = n_column.next(); emergency.createRelationshipTo(procedure, EmergencyRelationshipType.INSTANTIATE); tx.success(); } finally { tx.finish(); } } @Override public String getProcedureAttachedToVehicle(String vehicleId) { Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start v=(vehicles, 'vehicleId:" + vehicleId + "') match (v) <-[USE]- (w) return w"); ExecutionResult result = engine.execute(query); if (result.isEmpty()) { throw new IllegalStateException("No Procedure attached to the Vehicle " + vehicleId); } Iterator<Node> n_column = result.columnAs("w"); Node procedure = n_column.next(); String procedureId = (String) procedure.getProperty("procedureId"); tx.success(); return procedureId; } finally { tx.finish(); } } @Override public String getCallAttachedToEmergency(String emergencyId) { Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start e=(emergencies, 'emergencyId:" + emergencyId + "') match (e) <-[CREATES]- (c) return c"); ExecutionResult result = engine.execute(query); if (result.isEmpty()) { throw new IllegalStateException("No Call attached to the Emergency " + emergencyId); } Iterator<Node> n_column = result.columnAs("c"); Node call = n_column.next(); String callId = (String) call.getProperty("callId"); tx.success(); return callId; } finally { tx.finish(); } } @Override public String getEmergencyAttachedToCall(String callId) { Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start c=(calls, 'callId:" + callId + "') match (c) -[CREATES]-> (e) return e"); ExecutionResult result = engine.execute(query); if (result.isEmpty()) { throw new IllegalStateException("No Emergency attached to the Call " + callId); } Iterator<Node> n_column = result.columnAs("e"); Node call = n_column.next(); String emergencyId = (String) call.getProperty("emergencyId"); tx.success(); return emergencyId; } finally { tx.finish(); } } @Override public String newVehicleId() { Transaction tx = graphDb.beginTx(); String vehicleId = "Vehicle-" + UUID.randomUUID().toString(); try { Node vehicleNode = graphDb.createNode(); vehicleNode.setProperty("vehicleId", vehicleId); vehicleNode.setProperty("name", vehicleId); this.vehiclesIndex.add(vehicleNode, "vehicleId", vehicleId); tx.success(); } finally { tx.finish(); } return vehicleId; } @Override public void attachVehicle(String procedureId, String vehicleId) { System.out.println(">>>> Attaching Vehicle " + vehicleId + " to Procedure " + procedureId); Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start n=(procedures, 'procedureId:" + procedureId + "') return n"); ExecutionResult result = engine.execute(query); Iterator<Node> n_column = result.columnAs("n"); Node procedure = n_column.next(); query = parser.parse("start n=(vehicles, 'vehicleId:" + vehicleId + "') return n"); result = engine.execute(query); n_column = result.columnAs("n"); Node vehicle = n_column.next(); procedure.createRelationshipTo(vehicle, EmergencyRelationshipType.USE); tx.success(); } finally { tx.finish(); } } @Override public void attachProcedures(String parentProcedureId, String childProcedureId) { System.out.println(">>>> Attaching Procedure " + childProcedureId + " to Procedure " + parentProcedureId); Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start n=(procedures, 'procedureId:" + parentProcedureId + "') return n"); ExecutionResult result = engine.execute(query); Iterator<Node> n_column = result.columnAs("n"); Node parentProcedure = n_column.next(); query = parser.parse("start n=(procedures, 'procedureId:" + childProcedureId + "') return n"); result = engine.execute(query); n_column = result.columnAs("n"); Node childProcedure = n_column.next(); parentProcedure.createRelationshipTo(childProcedure, EmergencyRelationshipType.SUB); tx.success(); } finally { tx.finish(); } } @Override public String newServiceChannelId() { Transaction tx = graphDb.beginTx(); String channelId = "Channel-" + UUID.randomUUID().toString(); try { Node channelNode = graphDb.createNode(); channelNode.setProperty("channelId", channelId); channelNode.setProperty("name", channelId); this.channelsIndex.add(channelNode, "channelId", channelId); tx.success(); } finally { tx.finish(); } return channelId; } @Override public void attachServiceChannel(String emergencyId, String channelId) { Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start n=(emergencies, 'emergencyId:" + emergencyId + "') return n"); ExecutionResult result = engine.execute(query); Iterator<Node> n_column = result.columnAs("n"); Node emergency = n_column.next(); query = parser.parse("start n=(channels, 'channelId:" + channelId + "') return n"); result = engine.execute(query); n_column = result.columnAs("n"); Node channel = n_column.next(); emergency.createRelationshipTo(channel, EmergencyRelationshipType.CONSUME); tx.success(); } finally { tx.finish(); } } @Override public void detachVehicle(String vehicleId) { Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start n=(vehicles, 'vehicleId:" + vehicleId + "') return n"); ExecutionResult result = engine.execute(query); Iterator<Node> n_column = result.columnAs("n"); Node vehicle = n_column.next(); //Removing the node from the index this.vehiclesIndex.remove(vehicle); for (Relationship rel : vehicle.getRelationships()) { rel.delete(); } //Deleting the node from the graph vehicle.delete(); tx.success(); } finally { tx.finish(); } } @Override public void detachProcedure(String procedureId) { Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start n=(procedures, 'procedureId:" + procedureId + "') return n"); ExecutionResult result = engine.execute(query); Iterator<Node> n_column = result.columnAs("n"); Node procedure = n_column.next(); //Removing the node from the index this.proceduresIndex.remove(procedure); for (Relationship rel : procedure.getRelationships()) { rel.delete(); } //Deleting the node from the graph procedure.delete(); tx.success(); } finally { tx.finish(); } } @Override public void detachEmergency(String emergencyId) { Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start n=(emergencies, 'emergencyId:" + emergencyId + "') return n"); ExecutionResult result = engine.execute(query); Iterator<Node> n_column = result.columnAs("n"); Node emergency = n_column.next(); //Removing the node from the index this.emergenciesIndex.remove(emergency); for (Relationship rel : emergency.getRelationships()) { rel.delete(); } //Deleting the node from the graph emergency.delete(); tx.success(); } finally { tx.finish(); } } @Override public void detachServiceChannel(String serviceChannelId) { Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start n=(channels, 'channelId:" + serviceChannelId + "') return n"); ExecutionResult result = engine.execute(query); Iterator<Node> n_column = result.columnAs("n"); Node channel = n_column.next(); //Removing the node from the index this.channelsIndex.remove(channel); for (Relationship rel : channel.getRelationships()) { rel.delete(); } //Deleting the node from the graph channel.delete(); tx.success(); } finally { tx.finish(); } } @Override public void detachPatient(String patientId) { Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start n=(patients, 'patientId:" + patientId + "') return n"); ExecutionResult result = engine.execute(query); Iterator<Node> n_column = result.columnAs("n"); Node patient = n_column.next(); //Removing the node from the index this.channelsIndex.remove(patient); for (Relationship rel : patient.getRelationships()) { rel.delete(); } //Deleting the node from the graph patient.delete(); tx.success(); } finally { tx.finish(); } } @Override public void detachEmergencyEntityBuilding(String entityBuildingId) { Transaction tx = graphDb.beginTx(); try { CypherParser parser = new CypherParser(); ExecutionEngine engine = new ExecutionEngine(this.graphDb); Query query = parser.parse("start n=(buildings, 'buildingId:" + entityBuildingId + "') return n"); ExecutionResult result = engine.execute(query); Iterator<Node> n_column = result.columnAs("n"); Node building = n_column.next(); //Removing the node from the index this.buildingsIndex.remove(building); for (Relationship rel : building.getRelationships()) { rel.delete(); } //Deleting the node from the graph building.delete(); tx.success(); } finally { tx.finish(); } } @Override public void clear() { this.graphDb.shutdown(); } }