/** * {@inheritDoc} */ @Override public void doRefresh(IProgressMonitor monitor, IRootEditor rootEditor) { monitor.beginTask("Loading trace details..", IProgressMonitor.UNKNOWN); if (traceId != null) { // calculate the invocation trees to show spanTree = new InvocationTreeBuilder().setTraceId(traceId).setSpanService(spanService).setInvocationService(invocationDataAccessService).setMode(Mode.ONLY_SPANS_WITH_SDK).build(); InvocationTreeBuilder builder = new InvocationTreeBuilder().setTraceId(traceId).setSpanService(spanService).setInvocationService(invocationDataAccessService).setMode(Mode.ALL); final InvocationTreeElement fullTree = builder.build(); Display.getDefault().asyncExec(new Runnable() { @Override public void run() { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); IWorkbenchPage page = window.getActivePage(); IRootEditor rootEditor = (IRootEditor) page.getActiveEditor(); rootEditor.setDataInput(Collections.singletonList(fullTree)); } }); } monitor.done(); }
/** * Creates a new {@link InvocationTreeElement} without a parent. * * @param dataElement * the data element of the created {@link InvocationTreeElement} * @return the newly created {@link InvocationTreeElement} */ private InvocationTreeElement createTreeElement(Object dataElement) { return createTreeElement(dataElement, null); }
/** * Builds the tree. * * @return The root {@link InvocationTreeElement} of the resulting tree. If no tree could be * built, e.g. when finding no root element <code>null</code> will be returned. */ public InvocationTreeElement build() { prepare(); tree = findRoot(); if (tree == null) { return null; } resolve(); sortChildren(tree); resolveSpanDetails(); return tree; }
@Test(expectedExceptions = IllegalStateException.class) public void noTraceId() { builder.setSpanService(spanService).setInvocationService(invocationService); builder.build(); }
/** * Resolves a span element. * * @param parent * a {@link InvocationTreeElement} from type {@link TreeElementType#SPAN}. */ private void resolveSpan(InvocationTreeElement parent) { Span currentSpan = (Span) parent.getDataElement(); if (!currentSpan.isCaller()) { // server span - expect invocation sequence for (InvocationSequenceData data : invocationSequences) { if (InvocationSequenceDataHelper.hasSpanIdent(data) && data.getSpanIdent().equals(currentSpan.getSpanIdent())) { InvocationTreeElement child = createTreeElement(data, parent); resolveInvocationSequence(child); } } } for (Span span : spans) { // if span is already in the tree, skip it if (isSpanInTree(span.getSpanIdent())) { continue; } if (span.getParentSpanId() == currentSpan.getSpanIdent().getId()) { InvocationTreeElement child = createTreeElement(span, parent); resolveSpan(child); } } }
@Test public void disabledCache() { InvocationSequenceData invoc01 = createSequence(null); builder.setMode(Mode.SINGLE).setInvocationSequence(invoc01); InvocationTreeElement treeOne = builder.build(); InvocationTreeElement treeTwo = builder.build(); assertThat(treeOne, is(not(sameInstance(treeTwo)))); }
@Test public void buildOneInvocationSequenceWithSpan() { Span span01 = createServerSpan(null); InvocationSequenceData invoc01 = createSequence(span01); InvocationSequenceData _invoc02 = createSequence(null); invoc01.getNestedSequences().add(_invoc02); doReturn(span01).when(spanService).get(span01.getSpanIdent()); builder.setSpanService(spanService).setMode(Mode.SINGLE).setInvocationSequence(invoc01); InvocationTreeElement tree = builder.build(); Map<Object, InvocationTreeElement> lookupMap = InvocationTreeUtil.buildLookupMap(tree); assertThat(lookupMap.size(), is(3)); assertThat(tree.getDataElement(), is(span01)); assertThat(tree.getChildren(), contains(hasProperty("dataElement", is(invoc01)))); verify(spanService).get(span01.getSpanIdent()); verifyNoMoreInteractions(spanService); verifyZeroInteractions(invocationService); }
Optional span = getSpan(rootSequence.getSpanIdent()); rootDataElement = span.orElse(rootSequence); } else { InvocationTreeElement element = createTreeElement(rootDataElement); element.setRoot(true); return element; InvocationTreeElement element = createTreeElement(rootSpan.get()); element.setRoot(true); return element; InvocationTreeElement element = createTreeElement(rootSequence.get()); element.setRoot(true); return element;
if (InvocationSequenceDataHelper.hasSpanIdent(currentData) && !isSpanInTree(currentData.getSpanIdent())) { Optional<Span> optionalSpan = getSpan(currentData.getSpanIdent()); if (span.isCaller()) { child = createTreeElement(span, parent); } else { child = createTreeElement(span, parent); resolveSpan(child); InvocationTreeElement newRoot = createTreeElement(currentData.getSpanIdent()); newRoot.addChild(parent); createTreeElement(currentData.getSpanIdent(), parent); InvocationTreeElement child = createTreeElement(data, parent); resolveInvocationSequence(child);
@Test public void multipleCalls() { InvocationSequenceData invoc01 = createSequence(null); builder.setMode(Mode.SINGLE).setInvocationSequence(invoc01); InvocationTreeElement treeOne = builder.build(); InvocationTreeElement treeTwo = builder.build(); assertThat(treeOne, is(not(sameInstance(treeTwo)))); }
doReturn(span04).when(spanService).get(span04.getSpanIdent()); builder.setSpanService(spanService).setMode(Mode.SINGLE).setInvocationSequence(invoc03); InvocationTreeElement tree = builder.build();
@Test public void buildWithNestedExceptions() { Span span01 = createServerSpan(null); InvocationSequenceData invoc01 = createSequence(span01); InvocationSequenceData _invoc02 = createSequence(null); invoc01.getNestedSequences().add(_invoc02); invoc01.setNestedExceptions(true); doReturn(Arrays.asList(span01)).when(spanService).getSpans(1337L); doReturn(Arrays.asList(invoc01)).when(invocationService).getInvocationSequenceDetail(1337L); builder.setSpanService(spanService).setInvocationService(invocationService).setTraceId(1337L); InvocationTreeElement tree = builder.build(); Map<Object, InvocationTreeElement> lookupMap = InvocationTreeUtil.buildLookupMap(tree); assertThat(lookupMap.size(), is(3)); assertThat(tree.hasNestedExceptions(), is(true)); assertThat(tree.hasNestedSqls(), is(false)); }
@Test public void buildOneInvocationSequenceWithSpanWithoutSpanService() { Span span01 = createServerSpan(null); InvocationSequenceData invoc01 = createSequence(span01); InvocationSequenceData _invoc02 = createSequence(null); invoc01.getNestedSequences().add(_invoc02); builder.setMode(Mode.SINGLE).setInvocationSequence(invoc01); InvocationTreeElement tree = builder.build(); Map<Object, InvocationTreeElement> lookupMap = InvocationTreeUtil.buildLookupMap(tree); assertThat(lookupMap.size(), is(3)); assertThat(tree.getDataElement(), isA((Class) SpanIdent.class)); assertThat(tree.getChildren(), contains(hasProperty("dataElement", is(invoc01)))); verifyZeroInteractions(spanService, invocationService); }
@Test public void buildWithNestedSQLs() { Span span01 = createServerSpan(null); InvocationSequenceData invoc01 = createSequence(span01); InvocationSequenceData _invoc02 = createSequence(null); invoc01.getNestedSequences().add(_invoc02); invoc01.setNestedSqlStatements(true); doReturn(Arrays.asList(span01)).when(spanService).getSpans(1337L); doReturn(Arrays.asList(invoc01)).when(invocationService).getInvocationSequenceDetail(1337L); builder.setSpanService(spanService).setInvocationService(invocationService).setTraceId(1337L); InvocationTreeElement tree = builder.build(); Map<Object, InvocationTreeElement> lookupMap = InvocationTreeUtil.buildLookupMap(tree); assertThat(lookupMap.size(), is(3)); assertThat(tree.hasNestedExceptions(), is(false)); assertThat(tree.hasNestedSqls(), is(true)); } }
@Test public void buildOneInvocationSequence() { InvocationSequenceData invoc01 = createSequence(null); InvocationSequenceData _invoc02 = createSequence(null); InvocationSequenceData _invoc03 = createSequence(null); InvocationSequenceData _invoc04 = createSequence(null); invoc01.getNestedSequences().add(_invoc02); _invoc02.getNestedSequences().add(_invoc03); invoc01.getNestedSequences().add(_invoc04); builder.setMode(Mode.SINGLE).setInvocationSequence(invoc01); InvocationTreeElement tree = builder.build(); Map<Object, InvocationTreeElement> lookupMap = InvocationTreeUtil.buildLookupMap(tree); assertThat(lookupMap.size(), is(4)); assertThat(tree.getDataElement(), is(invoc01)); assertThat(tree.getChildren(), contains(hasProperty("dataElement", is(_invoc02)), hasProperty("dataElement", is(_invoc04)))); assertThat(tree.getChildren().get(0).getChildren(), contains(hasProperty("dataElement", is(_invoc03)))); assertThat(tree.getChildren().get(1).getChildren(), is(empty())); verifyZeroInteractions(spanService, invocationService); }
@Test public void buildTraceWithoutSdkSpans() { Span span01 = createServerSpan(null); Span span02 = createServerSpan(span01); Span span03 = createSdkSpan(span01); InvocationSequenceData invoc01 = createSequence(span01); InvocationSequenceData _invoc02 = createSequence(span02); invoc01.getNestedSequences().add(_invoc02); doReturn(Arrays.asList(span01, span02, span03)).when(spanService).getSpans(1337L); doReturn(Arrays.asList(invoc01)).when(invocationService).getInvocationSequenceDetail(1337L); builder.setSpanService(spanService).setInvocationService(invocationService).setTraceId(1337L); InvocationTreeElement tree = builder.build(); Map<Object, InvocationTreeElement> lookupMap = InvocationTreeUtil.buildLookupMap(tree); assertThat(lookupMap.size(), is(4)); assertThat(tree.getDataElement(), is(span01)); for (Object data : new Object[] { span01, span02, invoc01, _invoc02 }) { assertThat(InvocationTreeUtil.lookupTreeElement(lookupMap, data), is(not(nullValue()))); } assertThat(InvocationTreeUtil.lookupTreeElement(lookupMap, span03), is(nullValue())); verify(spanService).getSpans(1337L); verify(invocationService).getInvocationSequenceDetail(1337L); verifyNoMoreInteractions(spanService, invocationService); }
@Test public void buildTraceManyMissingSpans() { Span span01 = createServerSpan(null); Span span02 = createServerSpan(span01); Span span03 = createClientSpan(span01); Span span04 = createServerSpan(span01); InvocationSequenceData invoc01 = createSequence(span01); InvocationSequenceData _invoc02 = createSequence(span02); InvocationSequenceData _invoc03 = createSequence(span03); InvocationSequenceData _invoc04 = createSequence(span04); invoc01.getNestedSequences().addAll(Arrays.asList(_invoc02, _invoc03, _invoc04)); doReturn(Arrays.asList(span01)).when(spanService).getSpans(1337L); doReturn(Arrays.asList(invoc01)).when(invocationService).getInvocationSequenceDetail(1337L); builder.setSpanService(spanService).setInvocationService(invocationService).setTraceId(1337L); InvocationTreeElement tree = builder.build(); Map<Object, InvocationTreeElement> lookupMap = InvocationTreeUtil.buildLookupMap(tree); assertThat(lookupMap.size(), is(8)); assertThat(tree.getDataElement(), is(span01)); for (Object data : new Object[] { span01, span02, span03, span04, invoc01, _invoc02, _invoc03, _invoc04 }) { assertThat(InvocationTreeUtil.lookupTreeElement(lookupMap, data), is(not(nullValue()))); } verify(spanService).getSpans(1337L); verify(invocationService).getInvocationSequenceDetail(1337L); verifyNoMoreInteractions(spanService, invocationService); }
@Test public void buildTrace() { Span span01 = createServerSpan(null); Span span02 = createServerSpan(span01); Span span03 = createClientSpan(span02); Span span04 = createServerSpan(span03); InvocationSequenceData invoc01 = createSequence(span01); InvocationSequenceData _invoc02 = createSequence(span02); InvocationSequenceData invoc03 = createSequence(span02); InvocationSequenceData _invoc04 = createSequence(span03); invoc01.getNestedSequences().add(_invoc02); invoc03.getNestedSequences().add(_invoc04); doReturn(Arrays.asList(span01, span02, span03, span04)).when(spanService).getSpans(1337L); doReturn(Arrays.asList(invoc01, invoc03)).when(invocationService).getInvocationSequenceDetail(1337L); builder.setSpanService(spanService).setInvocationService(invocationService).setTraceId(1337L); InvocationTreeElement tree = builder.build(); Map<Object, InvocationTreeElement> lookupMap = InvocationTreeUtil.buildLookupMap(tree); assertThat(lookupMap.size(), is(8)); assertThat(tree.getDataElement(), is(span01)); for (Object data : new Object[] { span01, span02, span03, span04, invoc01, _invoc02, invoc03, _invoc04 }) { assertThat(InvocationTreeUtil.lookupTreeElement(lookupMap, data), is(not(nullValue()))); } verify(spanService).getSpans(1337L); verify(invocationService).getInvocationSequenceDetail(1337L); verifyNoMoreInteractions(spanService, invocationService); }
@Test public void buildTraceOnlySpans() { Span span01 = createServerSpan(null); Span span02 = createServerSpan(span01); Span span03 = createClientSpan(span02); Span span04 = createServerSpan(span03); Span span05 = createSdkSpan(span02); InvocationSequenceData invoc01 = createSequence(span01); InvocationSequenceData _invoc02 = createSequence(span02); InvocationSequenceData invoc03 = createSequence(span02); InvocationSequenceData _invoc04 = createSequence(span03); invoc01.getNestedSequences().add(_invoc02); invoc03.getNestedSequences().add(_invoc04); doReturn(Arrays.asList(span01, span02, span03, span04, span05)).when(spanService).getSpans(1337L); doReturn(Arrays.asList(invoc01, invoc03)).when(invocationService).getInvocationSequenceDetail(1337L); builder.setSpanService(spanService).setInvocationService(invocationService).setTraceId(1337L).setMode(Mode.ONLY_SPANS_WITH_SDK); InvocationTreeElement tree = builder.build(); Map<Object, InvocationTreeElement> lookupMap = InvocationTreeUtil.buildLookupMap(tree); assertThat(lookupMap.size(), is(5)); assertThat(tree.getDataElement(), is(span01)); for (Object data : new Object[] { span01, span02, span03, span04, span05 }) { assertThat(InvocationTreeUtil.lookupTreeElement(lookupMap, data), is(not(nullValue()))); } for (Object data : new Object[] { invoc01, _invoc02, invoc03, _invoc04 }) { assertThat(InvocationTreeUtil.lookupTreeElement(lookupMap, data), is(nullValue())); } verify(spanService).getSpans(1337L); verify(invocationService).getInvocationSequenceDetail(1337L); verifyNoMoreInteractions(spanService, invocationService); }
@Test public void buildTraceWithMissingInvocationSequence() { Span span01 = createServerSpan(null); Span span02 = createServerSpan(span01); Span span03 = createClientSpan(span02); Span span04 = createServerSpan(span03); InvocationSequenceData invoc01 = createSequence(span01); InvocationSequenceData _invoc02 = createSequence(span02); InvocationSequenceData invoc03 = createSequence(span02); InvocationSequenceData _invoc04 = createSequence(span03); invoc01.getNestedSequences().add(_invoc02); invoc03.getNestedSequences().add(_invoc04); doReturn(Arrays.asList(span01, span02, span03, span04)).when(spanService).getSpans(1337L); builder.setSpanService(spanService).setInvocationService(invocationService).setTraceId(1337L); InvocationTreeElement tree = builder.build(); Map<Object, InvocationTreeElement> lookupMap = InvocationTreeUtil.buildLookupMap(tree); assertThat(lookupMap.size(), is(4)); assertThat(tree.getDataElement(), is(span01)); assertThat(tree.getChildren(), contains(hasProperty("dataElement", is(span02)))); assertThat(tree.getChildren().get(0).getChildren(), contains(hasProperty("dataElement", is(span03)))); assertThat(tree.getChildren().get(0).getChildren().get(0).getChildren(), contains(hasProperty("dataElement", is(span04)))); assertThat(tree.getChildren().get(0).getChildren().get(0).getChildren().get(0).getChildren(), is(empty())); verify(spanService).getSpans(1337L); verify(invocationService).getInvocationSequenceDetail(1337L); verifyNoMoreInteractions(spanService, invocationService); }