private Long getChild(TraceRelationship rel, Long parent) { if ((rel.getRelationhsip() == Relationship.PARENT_OF || rel.getRelationhsip() == Relationship.POTENTIAL_PARENT_OF) && rel.getFrom().equals(parent)) { return rel.getTo(); } if (rel.getRelationhsip() == Relationship.POTENTIAL_CHILD_OF && rel.getTo().equals(parent)) { return rel.getFrom(); } return null; }
public synchronized void addRelationship(final Relationship relationship, final ShallowTraceBuilder from, final ShallowTraceBuilder to) { if (_relationships.size() < _maxTraceBuildersPerTrace) { TraceRelationship rel = new TraceRelationship(from, to, relationship); _relationships.add(rel); } }
traceMap.computeIfAbsent(rel._to.getId(), key -> rel._to.build()); switch (rel.getRelationhsip()) { case SUCCESSOR_OF: relationships.remove(new TraceRelationship(rel._from, rel._to, Relationship.POSSIBLE_SUCCESSOR_OF)); relationships.add(rel); break; case POSSIBLE_SUCCESSOR_OF: if (!relationships.contains(new TraceRelationship(rel._from, rel._to, Relationship.SUCCESSOR_OF))) { relationships.add(rel); relationships.remove(new TraceRelationship(rel._to, rel._from, Relationship.POTENTIAL_PARENT_OF)); relationships.add(new TraceRelationship(rel._to, rel._from, Relationship.PARENT_OF)); break; case POTENTIAL_CHILD_OF: if (!relationships.contains(new TraceRelationship(rel._to, rel._from, Relationship.PARENT_OF))) { relationships.add(new TraceRelationship(rel._to, rel._from, Relationship.POTENTIAL_PARENT_OF)); if (!relationships.contains(new TraceRelationship(rel._from, rel._to, Relationship.PARENT_OF))) { relationships.add(rel); relationships.remove(new TraceRelationship(rel._from, rel._to, Relationship.POTENTIAL_PARENT_OF)); relationships.add(rel); break;
/** * Populates sets with ids of tasks that have parent and ids of tasks that have potential * parents with number of potential parents. * Validates that task can have only one parent but many potential parents. */ private void assertAndFindParent(Trace trace, Set<Long> tasksWithParent, Map<Long, Integer> tasksWithPotentialParent) { for (TraceRelationship rel : trace.getRelationships()) { if (rel.getRelationhsip() == Relationship.PARENT_OF) { assertFalse(tasksWithParent.contains(rel.getTo())); tasksWithParent.add(rel.getTo()); } else if (rel.getRelationhsip() == Relationship.POTENTIAL_PARENT_OF) { if (!tasksWithPotentialParent.containsKey(rel.getTo())) { tasksWithPotentialParent.put(rel.getTo(), 0); } tasksWithPotentialParent.put(rel.getTo(), tasksWithPotentialParent.get(rel.getTo()) + 1); } } }
@Test public void testCustomBuilding() throws IOException { final String json = buildJson( new String[] { traceStr(1, "parent", ResultType.UNFINISHED, false), traceStr(2, "child", ResultType.UNFINISHED, false), traceStr(3, "predecessor", ResultType.UNFINISHED, false) }, new String[] { hierStr(1, 2), orderStr(3, 1) }, "test", 0L); final Trace trace; try { trace = decodeString(json); } catch (IOException e) { fail("JSON parse failed. Document:\n" + json + "\nError: " + e.toString()); return; } assertEquals("parent", trace.getTraceMap().get(1L).getName()); assertEquals(ResultType.UNFINISHED, trace.getTraceMap().get(1L).getResultType()); assertEquals(2, trace.getRelationships().size()); String childName = null; String predecessorName = null; for (TraceRelationship rel : trace.getRelationships()) { if (rel.getRelationhsip() == Relationship.PARENT_OF) { childName = trace.getTraceMap().get(rel.getTo()).getName(); } else if (rel.getRelationhsip() == Relationship.SUCCESSOR_OF) { predecessorName = trace.getTraceMap().get(rel.getTo()).getName(); } } assertEquals("child", childName); assertEquals("predecessor", predecessorName); }
traceMap.computeIfAbsent(rel._to.getId(), key -> rel._to.build()); switch (rel.getRelationhsip()) { case SUCCESSOR_OF: relationships.remove(new TraceRelationship(rel._from, rel._to, Relationship.POSSIBLE_SUCCESSOR_OF)); relationships.add(rel); break; case POSSIBLE_SUCCESSOR_OF: if (!relationships.contains(new TraceRelationship(rel._from, rel._to, Relationship.SUCCESSOR_OF))) { relationships.add(rel); relationships.remove(new TraceRelationship(rel._to, rel._from, Relationship.POTENTIAL_PARENT_OF)); relationships.add(new TraceRelationship(rel._to, rel._from, Relationship.PARENT_OF)); break; case POTENTIAL_CHILD_OF: if (!relationships.contains(new TraceRelationship(rel._to, rel._from, Relationship.PARENT_OF))) { relationships.add(new TraceRelationship(rel._to, rel._from, Relationship.POTENTIAL_PARENT_OF)); if (!relationships.contains(new TraceRelationship(rel._from, rel._to, Relationship.PARENT_OF))) { relationships.add(rel); relationships.remove(new TraceRelationship(rel._from, rel._to, Relationship.POTENTIAL_PARENT_OF)); relationships.add(rel); break;
private static void writeRelationships(final Trace trace, final JsonGenerator generator) throws IOException { generator.writeArrayFieldStart(JsonTraceCodec.RELATIONSHIPS); for (TraceRelationship rel : trace.getRelationships()) { generator.writeStartObject(); generator.writeStringField(JsonTraceCodec.RELATIONSHIP_RELATIONSHIP, rel.getRelationhsip().name()); generator.writeNumberField(JsonTraceCodec.RELATIONSHIP_FROM, rel.getFrom()); generator.writeNumberField(JsonTraceCodec.RELATIONSHIP_TO, rel.getTo()); generator.writeEndObject(); } generator.writeEndArray(); }
private static Set<TraceRelationship> parseRelationships(final JsonNode rootNode, final Map<Long, ShallowTrace> traceMap) throws IOException { Set<TraceRelationship> relationships = new HashSet<>(); for (JsonNode node : getField(rootNode, JsonTraceCodec.RELATIONSHIPS)) { final Relationship relationship = Relationship.valueOf(getTextField(node, JsonTraceCodec.RELATIONSHIP_RELATIONSHIP)); final long from = getIntField(node, JsonTraceCodec.RELATIONSHIP_FROM); final long to = getIntField(node, JsonTraceCodec.RELATIONSHIP_TO); if (!traceMap.containsKey(from)) { throw new IOException("Missing trace with id: " + from + " referenced by relationship: " + relationship); } if (!traceMap.containsKey(to)) { throw new IOException("Missing trace with id: " + to + " referenced by relationship: " + relationship); } relationships.add(new TraceRelationship(new ShallowTraceBuilder(traceMap.get(from)), new ShallowTraceBuilder(traceMap.get(to)), relationship)); } return relationships; }
private static void writeRelationships(final Trace trace, final JsonGenerator generator) throws IOException { generator.writeArrayFieldStart(JsonTraceCodec.RELATIONSHIPS); for (TraceRelationship rel : trace.getRelationships()) { generator.writeStartObject(); generator.writeStringField(JsonTraceCodec.RELATIONSHIP_RELATIONSHIP, rel.getRelationhsip().name()); generator.writeNumberField(JsonTraceCodec.RELATIONSHIP_FROM, rel.getFrom()); generator.writeNumberField(JsonTraceCodec.RELATIONSHIP_TO, rel.getTo()); generator.writeEndObject(); } generator.writeEndArray(); }
@SuppressWarnings("deprecation") @Test public void testTraceWithSuccessChild() throws InterruptedException { final Task<String> task = value("taskName", "value"); final Task<?> seq = Tasks.seq(Arrays.asList(task)); runAndWait("TestTaskToTrace.testTraceWithSuccessChild", seq); verifyShallowTrace(task); verifyShallowTrace(seq); assertEquals(1, getRelationships(seq.getTrace(), seq.getId()).size()); assertTrue(seq.getTrace().getRelationships() .contains(new TraceRelationship(seq.getShallowTraceBuilder(), task.getShallowTraceBuilder(), Relationship.PARENT_OF))); }
}); for (TraceRelationship rel : trace.getRelationships()) { builder.addRelationship(rel.getRelationhsip(), traceMap.get(rel.getFrom()), traceMap.get(rel.getTo()));
new TraceRelationship(parent.getShallowTraceBuilder(), a.getShallowTraceBuilder(), Relationship.PARENT_OF))); assertTrue(parent.getTrace().getRelationships().contains( new TraceRelationship(parent.getShallowTraceBuilder(), b.getShallowTraceBuilder(), Relationship.PARENT_OF))); assertTrue(parent.getTrace().getRelationships().contains( new TraceRelationship(parent.getShallowTraceBuilder(), c.getShallowTraceBuilder(), Relationship.PARENT_OF))); assertTrue(parent.getTrace().getRelationships().contains( new TraceRelationship(parent.getShallowTraceBuilder(), d.getShallowTraceBuilder(), Relationship.PARENT_OF))); new TraceRelationship(d.getShallowTraceBuilder(), b.getShallowTraceBuilder(), Relationship.SUCCESSOR_OF))); assertTrue(parent.getTrace().getRelationships().contains( new TraceRelationship(d.getShallowTraceBuilder(), c.getShallowTraceBuilder(), Relationship.SUCCESSOR_OF))); assertTrue(parent.getTrace().getRelationships().contains( new TraceRelationship(b.getShallowTraceBuilder(), a.getShallowTraceBuilder(), Relationship.SUCCESSOR_OF))); assertTrue(parent.getTrace().getRelationships().contains( new TraceRelationship(c.getShallowTraceBuilder(), a.getShallowTraceBuilder(), Relationship.SUCCESSOR_OF)));
@Test public void testSideEffectsPredecessorTrace() throws InterruptedException, IOException { final Task<String> baseTask = value("base", "baseValue"); final Task<String> sideEffect = value("sideEffect", "sideEffectValue"); final Task<String> withSideEffect = baseTask.withSideEffect(x -> sideEffect); runAndWait("TestTaskToTrace.testSideEffectsPredecessorTrace", withSideEffect); assertTrue(sideEffect.await(5, TimeUnit.SECONDS)); assertEquals(2, getRelationships(withSideEffect.getTrace(), withSideEffect.getId()).size()); verifyShallowTrace(sideEffect); verifyShallowTrace(baseTask); assertTrue(withSideEffect.getTrace().getRelationships().toString(), withSideEffect.getTrace().getRelationships() .contains(new TraceRelationship(withSideEffect.getShallowTraceBuilder(), baseTask.getShallowTraceBuilder(), Relationship.PARENT_OF))); }
@Test public void testTraceWithEarlyFinish() throws InterruptedException { final Task<String> innerTask = value("xyz"); final Task<String> task = new BaseTask<String>() { @Override protected Promise<? extends String> run(final Context context) throws Exception { // We kick off a task that won't finish before the containing task // (this task) is finished. context.run(innerTask); return Promises.value("value"); } }; runAndWait("TestTaskToTrace.testTraceWithEarlyFinish", task); assertEquals(1, getRelationships(task.getTrace(), task.getId()).size()); assertTrue(task.getTrace().getRelationships() .contains(new TraceRelationship(task.getShallowTraceBuilder(), innerTask.getShallowTraceBuilder(), Relationship.POTENTIAL_PARENT_OF))); assertEquals(ResultType.EARLY_FINISH, task.getTrace().getTraceMap().get(innerTask.getId()).getResultType()); }
@Test public void testAddRelationship() { final ShallowTraceBuilder trace1 = new ShallowTraceBuilder(IdGenerator.getNextId()).setName("task1").setResultType(ResultType.UNFINISHED); final ShallowTraceBuilder trace2 = new ShallowTraceBuilder(IdGenerator.getNextId()).setName("task2").setResultType(ResultType.UNFINISHED); final TraceBuilder builder = new TraceBuilder(1024, "test", 0L); builder.addRelationship(Relationship.SUCCESSOR_OF, trace1, trace2); Trace trace = builder.build(); assertEquals(trace1.build(), trace.getTraceMap().get(trace1.getId())); assertEquals(trace2.build(), trace.getTraceMap().get(trace2.getId())); assertEquals(1, trace.getRelationships().size()); assertTrue(trace.getRelationships() .contains(new TraceRelationship(trace1, trace2, Relationship.SUCCESSOR_OF))); }
@Test public void testTraceWithPredecessorTrace() throws InterruptedException { final Task<String> predecessor = value("predecessor", "predecessorValue"); final Task<String> successor = value("successor", "successorValue"); final Task<?> seq = predecessor.andThen(successor); runAndWait("TestTaskToTrace.testTraceWithPredecessorTrace", seq); verifyShallowTrace(successor); verifyShallowTrace(predecessor); assertEquals(predecessor.getTrace(), successor.getTrace()); //expected relationship: PARENT_OF and SUCCESSOR_OF assertEquals(2, getRelationships(successor.getTrace(), successor.getId()).size()); assertTrue(successor.getTrace().getRelationships() .contains(new TraceRelationship(successor.getShallowTraceBuilder(), predecessor.getShallowTraceBuilder(), Relationship.SUCCESSOR_OF))); }
@Test public void testAddRelationshipTwice() { final ShallowTraceBuilder trace1 = new ShallowTraceBuilder(IdGenerator.getNextId()).setName("task1").setResultType(ResultType.UNFINISHED); final ShallowTraceBuilder trace2 = new ShallowTraceBuilder(IdGenerator.getNextId()).setName("task2").setResultType(ResultType.UNFINISHED); final TraceBuilder builder = new TraceBuilder(1024, "test", 0L); builder.addRelationship(Relationship.SUCCESSOR_OF, trace1, trace2); builder.addRelationship(Relationship.SUCCESSOR_OF, trace1, trace2); Trace trace = builder.build(); assertEquals(trace1.build(), trace.getTraceMap().get(trace1.getId())); assertEquals(trace2.build(), trace.getTraceMap().get(trace2.getId())); assertEquals(1, trace.getRelationships().size()); assertTrue(trace.getRelationships() .contains(new TraceRelationship(trace1, trace2, Relationship.SUCCESSOR_OF))); }
@Test public void testRelationshipRetention() { final TraceBuilder builder = new TraceBuilder(4096, "test", 0L); List<TraceRelationship> rels = new ArrayList<TraceRelationship>(); for (int i = 0; i < 4096; i++) { final ShallowTraceBuilder trace1 = new ShallowTraceBuilder(IdGenerator.getNextId()).setName("task1").setResultType(ResultType.UNFINISHED); final ShallowTraceBuilder trace2 = new ShallowTraceBuilder(IdGenerator.getNextId()).setName("task2").setResultType(ResultType.UNFINISHED); builder.addRelationship(Relationship.SUCCESSOR_OF, trace1, trace2); rels.add(new TraceRelationship(trace1, trace2, Relationship.SUCCESSOR_OF)); } for (int i = 0; i < 4096 * 10; i++) { final ShallowTraceBuilder trace1 = new ShallowTraceBuilder(IdGenerator.getNextId()).setName("task1").setResultType(ResultType.UNFINISHED); final ShallowTraceBuilder trace2 = new ShallowTraceBuilder(IdGenerator.getNextId()).setName("task2").setResultType(ResultType.UNFINISHED); builder.addRelationship(Relationship.SUCCESSOR_OF, trace1, trace2); } Trace trace = builder.build(); assertEquals(rels.size(), trace.getRelationships().size()); for (TraceRelationship rel : rels) { assertTrue(trace.getRelationships().contains(rel)); } }
public synchronized void addRelationship(final Relationship relationship, final ShallowTraceBuilder from, final ShallowTraceBuilder to) { if (_relationships.size() < _maxTraceBuildersPerTrace) { TraceRelationship rel = new TraceRelationship(from, to, relationship); _relationships.add(rel); } }