/** * Copyright 2014 IHTSDO * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.ihtsdo.otf.refset.graph.gao; import static org.ihtsdo.otf.refset.domain.RGC.END; import static org.ihtsdo.otf.refset.domain.RGC.ID; import static org.ihtsdo.otf.refset.domain.RGC.TYPE; import static org.ihtsdo.otf.refset.domain.RGC.START; import static org.ihtsdo.otf.refset.domain.RGC.ACTIVE; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Resource; import org.ihtsdo.otf.refset.domain.ChangeRecord; import org.ihtsdo.otf.refset.domain.Member; import org.ihtsdo.otf.refset.domain.Refset; import org.ihtsdo.otf.refset.exception.EntityNotFoundException; import org.ihtsdo.otf.refset.graph.RefsetGraphAccessException; import org.ihtsdo.otf.refset.graph.RefsetGraphFactory; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Repository; import com.thinkaurelius.titan.core.TitanGraph; import com.tinkerpop.blueprints.Direction; import com.tinkerpop.blueprints.Edge; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.gremlin.Tokens.T; import com.tinkerpop.gremlin.java.GremlinPipeline; /**class address history retrieval of Members or Refset * */ @Repository public class HistoryGao { private static final Logger LOGGER = LoggerFactory.getLogger(HistoryGao.class); private RefsetGraphFactory f; /** * @param factory the factory to set */ @Resource(name = "refsetGraphFactory") public void setFactory(RefsetGraphFactory factory) { this.f = factory; } /** * @param refsetId * @param from * @param to * @return * @throws RefsetGraphAccessException */ public Map<String, ChangeRecord<Member>> getAllMembersHistory(String refsetId, DateTime fromDate, DateTime toDate, Integer from, Integer to) throws RefsetGraphAccessException { LOGGER.debug("Getting all member history for refset id {}", refsetId); Map<String, ChangeRecord<Member>> history = new HashMap<String, ChangeRecord<Member>>(); TitanGraph g = null; try { g = f.getReadOnlyGraph(); Iterable<Vertex> vRs = g.query().has(TYPE, VertexType.refset.toString()).has(ID, refsetId).limit(1).vertices(); if (!vRs.iterator().hasNext()) { throw new EntityNotFoundException("Refset does not exist for given refset id " + refsetId); } Vertex vR = vRs.iterator().next(); GremlinPipeline<Vertex, Edge> fPipe = new GremlinPipeline<Vertex, Edge>(); fPipe.start(vR).inE(EdgeLabel.members.toString()).range(from, to); List<Edge> fls = fPipe.toList(); for (Edge e : fls) { Vertex v = e.getVertex(Direction.OUT); GremlinPipeline<Vertex, Edge> mhPipe = new GremlinPipeline<Vertex, Edge>(); mhPipe.start(v).outE(EdgeLabel.hasState.toString()) .has(END, T.lte, toDate.getMillis()) .has(START, T.gte, fromDate.getMillis()) .range(from, to); List<Edge> mhls = mhPipe.toList(); List<Member> ms = RefsetConvertor.getHistoryMembers(mhls); ChangeRecord<Member> cr = new ChangeRecord<Member>(); String rcId = e.getProperty(ID); cr.setRecord(ms); history.put(rcId, cr); } } catch (Exception e) { RefsetGraphFactory.rollback(g); LOGGER.error("Error getting refsets member history", e); throw new RefsetGraphAccessException(e.getMessage(), e); } finally { RefsetGraphFactory.shutdown(g); } return history; } /** * @param refsetId * @param referenceComponentId * @param from * @param to * @return * @throws RefsetGraphAccessException */ public ChangeRecord<Member> getMemberHistory(String refsetId, String id, DateTime fromDate, DateTime toDate, Integer from, Integer to) throws RefsetGraphAccessException { Object[] criteria = {id, fromDate, toDate, from, to}; LOGGER.debug("Getting member history for refset id {} and criteria {}", refsetId, criteria); ChangeRecord<Member> history = new ChangeRecord<Member>(); TitanGraph g = null; try { g = f.getReadOnlyGraph(); Iterable<Vertex> vRs = g.query().has(TYPE, VertexType.refset.toString()).has(ID, refsetId).limit(1).vertices(); if (!vRs.iterator().hasNext()) { throw new EntityNotFoundException("Refset does not exist for given refset id " + refsetId); } Vertex vR = vRs.iterator().next(); //get required members as per range GremlinPipeline<Vertex, Edge> fPipe = new GremlinPipeline<Vertex, Edge>(); fPipe.start(vR).inE(EdgeLabel.members.toString()).outV() .has(ID, T.eq, id).outE(EdgeLabel.hasState.toString()) .has(END, T.lte, toDate.getMillis()) .has(START, T.gte, fromDate.getMillis()) .range(from, to); List<Edge> fls = fPipe.toList(); List<Member> ms = RefsetConvertor.getHistoryMembers(fls); history.setRecord(ms); } catch (Exception e) { RefsetGraphFactory.rollback(g); LOGGER.error("Error getting refsets history", e); throw new RefsetGraphAccessException(e.getMessage(), e); } finally { RefsetGraphFactory.shutdown(g); } LOGGER.debug("Returning {} ", history); return history; } /** * @param refsetId * @param fromDate * @param toDate * @return * @throws RefsetGraphAccessException */ public ChangeRecord<Refset> getRefsetHeaderHistory(String refsetId, DateTime fromDate, DateTime toDate, Integer from, Integer to) throws RefsetGraphAccessException { Object[] criteria = {fromDate, toDate, from, to}; LOGGER.debug("Getting refset history for refset id {}, and criteria {}", refsetId, criteria); ChangeRecord<Refset> history = new ChangeRecord<Refset>(); TitanGraph g = null; try { g = f.getReadOnlyGraph(); Iterable<Vertex> vRs = g.query().has(TYPE, VertexType.refset.toString()).has(ID, refsetId).limit(1).vertices(); if (!vRs.iterator().hasNext()) { throw new EntityNotFoundException("Refset does not exist for given refset id " + refsetId); } Vertex vR = vRs.iterator().next(); //get required members as per range GremlinPipeline<Vertex, Edge> rPipe = new GremlinPipeline<Vertex, Edge>(); rPipe.start(vR).outE(EdgeLabel.hasState.toString()) .has(END, T.lte, toDate.getMillis()) .has(START, T.gte, fromDate.getMillis()) .range(from, to); List<Edge> ls = rPipe.toList(); List<Refset> rs = RefsetConvertor.getHistoryRefsets(ls); history.setRecord(rs); } catch (Exception e) { RefsetGraphFactory.rollback(g); LOGGER.error("Error getting refsets member history", e); throw new RefsetGraphAccessException(e.getMessage(), e); } finally { RefsetGraphFactory.shutdown(g); } return history; } /** * @param refsetId * @param fromDate * @param toDate * @param from * @param to * @return */ public Map<String, ChangeRecord<Member>> getAllMembersStateHistory( String refsetId, DateTime fromDate, DateTime toDate, int from, int to) throws RefsetGraphAccessException { LOGGER.debug("Getting all member state history for refset id {}", refsetId); Map<String, ChangeRecord<Member>> history = new HashMap<String, ChangeRecord<Member>>(); TitanGraph g = null; try { g = f.getReadOnlyGraph(); Iterable<Vertex> vRs = g.query().has(TYPE, VertexType.refset.toString()).has(ID, refsetId).limit(1).vertices(); if (!vRs.iterator().hasNext()) { throw new EntityNotFoundException("Refset does not exist for given refset id " + refsetId); } Vertex vR = vRs.iterator().next(); GremlinPipeline<Vertex, Edge> fPipe = new GremlinPipeline<Vertex, Edge>(); fPipe.start(vR).inE(EdgeLabel.members.toString()).range(from, to); List<Edge> fls = fPipe.toList(); for (Edge e : fls) { Vertex v = e.getVertex(Direction.OUT); GremlinPipeline<Vertex, Edge> mhPipe = new GremlinPipeline<Vertex, Edge>(); mhPipe.start(v).outE(EdgeLabel.hasState.toString()) .has(END, T.lte, toDate.getMillis()) .has(START, T.gte, fromDate.getMillis()) .inV().has(ACTIVE).has(TYPE, VertexType.hMember.toString()) .range(from, to); List<Edge> mhls = mhPipe.toList(); List<Member> ms = RefsetConvertor.getHistoryMembers(mhls); ChangeRecord<Member> cr = new ChangeRecord<Member>(); String rcId = e.getProperty(ID); cr.setRecord(ms); history.put(rcId, cr); } } catch (Exception e) { RefsetGraphFactory.rollback(g); LOGGER.error("Error getting refsets member history", e); throw new RefsetGraphAccessException(e.getMessage(), e); } finally { RefsetGraphFactory.shutdown(g); } return history; } /** * @param refsetId * @param fromDate * @param toDate * @param from * @param to * @return */ public ChangeRecord<Refset> getRefsetHeaderStateHistory(String refsetId, DateTime fromDate, DateTime toDate, int from, int to) throws RefsetGraphAccessException { Object[] criteria = {fromDate, toDate, from, to}; LOGGER.debug("Getting refset history for refset id {}, and criteria {}", refsetId, criteria); ChangeRecord<Refset> history = new ChangeRecord<Refset>(); TitanGraph g = null; try { g = f.getReadOnlyGraph(); Iterable<Vertex> vRs = g.query().has(TYPE, VertexType.refset.toString()).has(ID, refsetId).limit(1).vertices(); if (!vRs.iterator().hasNext()) { throw new EntityNotFoundException("Refset does not exist for given refset id " + refsetId); } Vertex vR = vRs.iterator().next(); //get required members as per range GremlinPipeline<Vertex, Vertex> rPipe = new GremlinPipeline<Vertex, Vertex>(); rPipe.start(vR).outE(EdgeLabel.hasState.toString()) .has(END, T.lte, toDate.getMillis()) .has(START, T.gte, fromDate.getMillis()).inV().has(ACTIVE).has(TYPE, VertexType.hMember.toString()) .range(from, to); List<Vertex> ls = rPipe.toList(); List<Refset> rs = RefsetConvertor.getStateRefsets(ls); history.setRecord(rs); } catch (Exception e) { RefsetGraphFactory.rollback(g); LOGGER.error("Error getting refsets member history", e); throw new RefsetGraphAccessException(e.getMessage(), e); } finally { RefsetGraphFactory.shutdown(g); } return history; } /** * @param refsetId * @param memberId * @param fromDate * @param toDate * @param from * @param to * @return */ public ChangeRecord<Member> getMemberStateHistory(String refsetId, String id, DateTime fromDate, DateTime toDate, int from, int to) throws RefsetGraphAccessException { Object[] criteria = {id, fromDate, toDate, from, to}; LOGGER.debug("Getting member history for refset id {} and criteria {}", refsetId, criteria); ChangeRecord<Member> history = new ChangeRecord<Member>(); TitanGraph g = null; try { g = f.getReadOnlyGraph(); Iterable<Vertex> vRs = g.query().has(TYPE, VertexType.refset.toString()).has(ID, refsetId).limit(1).vertices(); if (!vRs.iterator().hasNext()) { throw new EntityNotFoundException("Refset does not exist for given refset id " + refsetId); } Vertex vR = vRs.iterator().next(); //get required members as per range GremlinPipeline<Vertex, Vertex> fPipe = new GremlinPipeline<Vertex, Vertex>(); fPipe.start(vR).inE(EdgeLabel.members.toString()).outV() .has(ID, T.eq, id).outE(EdgeLabel.hasState.toString()) .has(END, T.lte, toDate.getMillis()) .has(START, T.gte, fromDate.getMillis()) .inV().has(ACTIVE).has(TYPE, VertexType.hMember.toString()) .range(from, to); List<Vertex> fls = fPipe.toList(); List<Member> ms = RefsetConvertor.getStateMembers(fls); history.setRecord(ms); } catch (Exception e) { RefsetGraphFactory.rollback(g); LOGGER.error("Error getting member state history", e); throw new RefsetGraphAccessException(e.getMessage(), e); } finally { RefsetGraphFactory.shutdown(g); } LOGGER.debug("Returning {} ", history); return history; } }