package io.lumify.securegraph.model.longRunningProcess; import com.google.inject.Inject; import io.lumify.core.model.longRunningProcess.LongRunningProcessRepository; import io.lumify.core.model.ontology.OntologyRepository; import io.lumify.core.model.properties.LumifyProperties; import io.lumify.core.model.properties.types.JsonLumifyProperty; import io.lumify.core.model.user.AuthorizationRepository; import io.lumify.core.model.user.UserRepository; import io.lumify.core.model.workQueue.WorkQueueRepository; import io.lumify.core.user.User; import org.json.JSONObject; import org.securegraph.*; import org.securegraph.util.ConvertingIterable; import java.util.List; import static com.google.common.base.Preconditions.checkNotNull; import static org.securegraph.util.IterableUtils.toList; public class SecureGraphLongRunningProcessRepository extends LongRunningProcessRepository { private final WorkQueueRepository workQueueRepository; private final UserRepository userRepository; private final Graph graph; private JsonLumifyProperty QUEUE_ITEM_JSON_PROPERTY = new JsonLumifyProperty("http://lumify.io/longRunningProcess#queueItemJson"); @Inject public SecureGraphLongRunningProcessRepository( AuthorizationRepository authorizationRepository, OntologyRepository ontologyRepository, UserRepository userRepository, WorkQueueRepository workQueueRepository, Graph graph) { this.userRepository = userRepository; this.workQueueRepository = workQueueRepository; this.graph = graph; authorizationRepository.addAuthorizationToGraph(VISIBILITY_STRING); } @Override public String enqueue(JSONObject longRunningProcessQueueItem, User user, Authorizations authorizations) { authorizations = getAuthorizations(user); Vertex userVertex = graph.getVertex(user.getUserId(), authorizations); checkNotNull(userVertex, "Could not find user with id: " + user.getUserId()); Visibility visibility = getVisibility(); VertexBuilder vertexBuilder = this.graph.prepareVertex(visibility); LumifyProperties.CONCEPT_TYPE.setProperty(vertexBuilder, LONG_RUNNING_PROCESS_CONCEPT_IRI, visibility); longRunningProcessQueueItem.put("enqueueTime", System.currentTimeMillis()); longRunningProcessQueueItem.put("userId", user.getUserId()); QUEUE_ITEM_JSON_PROPERTY.setProperty(vertexBuilder, longRunningProcessQueueItem, visibility); Vertex longRunningProcessVertex = vertexBuilder.save(authorizations); this.graph.addEdge(userVertex, longRunningProcessVertex, LONG_RUNNING_PROCESS_TO_USER_EDGE_IRI, visibility, authorizations); this.graph.flush(); longRunningProcessQueueItem.put("id", longRunningProcessVertex.getId()); this.workQueueRepository.pushLongRunningProcessQueue(longRunningProcessQueueItem); return longRunningProcessVertex.getId(); } public Authorizations getAuthorizations(User user) { Authorizations authorizations; authorizations = userRepository.getAuthorizations(user, VISIBILITY_STRING, UserRepository.VISIBILITY_STRING); return authorizations; } @Override public void beginWork(JSONObject longRunningProcessQueueItem) { super.beginWork(longRunningProcessQueueItem); updateVertexWithJson(longRunningProcessQueueItem); } @Override public void ack(JSONObject longRunningProcessQueueItem) { updateVertexWithJson(longRunningProcessQueueItem); } @Override public void nak(JSONObject longRunningProcessQueueItem, Throwable ex) { updateVertexWithJson(longRunningProcessQueueItem); } public void updateVertexWithJson(JSONObject longRunningProcessQueueItem) { String longRunningProcessGraphVertexId = longRunningProcessQueueItem.getString("id"); Authorizations authorizations = getAuthorizations(userRepository.getSystemUser()); Vertex vertex = this.graph.getVertex(longRunningProcessGraphVertexId, authorizations); checkNotNull(vertex, "Could not find long running process vertex: " + longRunningProcessGraphVertexId); QUEUE_ITEM_JSON_PROPERTY.setProperty(vertex, longRunningProcessQueueItem, getVisibility(), authorizations); this.graph.flush(); } @Override public List<JSONObject> getLongRunningProcesses(User user) { Authorizations authorizations = getAuthorizations(user); Vertex userVertex = graph.getVertex(user.getUserId(), authorizations); checkNotNull(userVertex, "Could not find user with id: " + user.getUserId()); Iterable<Vertex> longRunningProcessVertices = userVertex.getVertices(Direction.OUT, LONG_RUNNING_PROCESS_TO_USER_EDGE_IRI, authorizations); return toList(new ConvertingIterable<Vertex, JSONObject>(longRunningProcessVertices) { @Override protected JSONObject convert(Vertex longRunningProcessVertex) { JSONObject json = QUEUE_ITEM_JSON_PROPERTY.getPropertyValue(longRunningProcessVertex); json.put("id", longRunningProcessVertex.getId()); return json; } }); } @Override public JSONObject findById(String longRunningProcessId, User user) { Authorizations authorizations = getAuthorizations(user); Vertex vertex = this.graph.getVertex(longRunningProcessId, authorizations); if (vertex == null) { return null; } return QUEUE_ITEM_JSON_PROPERTY.getPropertyValue(vertex); } @Override public void cancel(String longRunningProcessId, User user) { Authorizations authorizations = getAuthorizations(userRepository.getSystemUser()); Vertex vertex = this.graph.getVertex(longRunningProcessId, authorizations); checkNotNull(vertex, "Could not find long running process vertex: " + longRunningProcessId); JSONObject json = QUEUE_ITEM_JSON_PROPERTY.getPropertyValue(vertex); json.put("canceled", true); QUEUE_ITEM_JSON_PROPERTY.setProperty(vertex, json, getVisibility(), getAuthorizations(user)); this.graph.flush(); } @Override public void reportProgress(JSONObject longRunningProcessQueueItem, double progressPercent, String message) { String longRunningProcessGraphVertexId = longRunningProcessQueueItem.getString("id"); Authorizations authorizations = getAuthorizations(userRepository.getSystemUser()); Vertex vertex = this.graph.getVertex(longRunningProcessGraphVertexId, authorizations); checkNotNull(vertex, "Could not find long running process vertex: " + longRunningProcessGraphVertexId); JSONObject json = QUEUE_ITEM_JSON_PROPERTY.getPropertyValue(vertex); json.put("progress", progressPercent); json.put("progressMessage", message); QUEUE_ITEM_JSON_PROPERTY.setProperty(vertex, json, getVisibility(), authorizations); this.graph.flush(); workQueueRepository.broadcastLongRunningProcessChange(json); } @Override public void delete(String longRunningProcessId, User authUser) { Authorizations authorizations = getAuthorizations(authUser); Vertex vertex = this.graph.getVertex(longRunningProcessId, authorizations); this.graph.removeVertex(vertex, authorizations); this.graph.flush(); } private Visibility getVisibility() { return new Visibility(VISIBILITY_STRING); } }