TracingSupportingHonoResource extends CoapResource { @Override public void handleRequest(final Exchange exchange) { final Span currentSpan = newSpan(exchange); final CoapExchange coapExchange = new CoapExchange(exchange, this); final Future<ResponseCode> responseCode; switch (exchange.getRequest().getCode()) { case POST: responseCode = createCoapContextForPost(coapExchange, currentSpan) .compose(coapContext -> applyTraceSamplingPriority(coapContext, currentSpan)) .compose(this::handlePost); break; case PUT: responseCode = createCoapContextForPut(coapExchange, currentSpan) .compose(coapContext -> applyTraceSamplingPriority(coapContext, currentSpan)) .compose(this::handlePut); break; default: final Response response = CoapErrorResponse.respond("unsupported method", ResponseCode.METHOD_NOT_ALLOWED); coapExchange.respond(response); responseCode = Future.succeededFuture(response.getCode()); break; } responseCode.otherwise(t -> { log.debug("error handling request", t); TracingHelper.logError(currentSpan, t); final Response response = CoapErrorResponse.respond(t, ResponseCode.INTERNAL_SERVER_ERROR); coapExchange.respond(response); return response.getCode(); }) .onComplete(r -> { log.debug("response: {}", r.result()); currentSpan.setTag("coap.response_code", r.result().toString()); currentSpan.finish(); }); } TracingSupportingHonoResource(
            final Tracer tracer,
            final String resourceName,
            final String adapterName,
            final TenantClientFactory tenantClientFactory); @Override Resource getChild(final String name); @Override void handleRequest(final Exchange exchange); @Override final void handleDELETE(final CoapExchange exchange); @Override final void handleFETCH(final CoapExchange exchange); @Override void handleGET(final CoapExchange exchange); @Override void handleIPATCH(final CoapExchange exchange); @Override void handlePATCH(final CoapExchange exchange); @Override void handlePOST(final CoapExchange exchange); @Override void handlePUT(final CoapExchange exchange);  }
@Test public void testHandleRequestExtractsParentTraceContext() { final SpanContext extractedContext = mock(SpanContext.class); when(tracer.extract(eq(Format.Builtin.BINARY), any(Binary.class))).thenReturn(extractedContext); final Request request = new Request(Code.POST); request.getOptions().addOption(new Option(CoapOptionInjectExtractAdapter.OPTION_TRACE_CONTEXT)); final Exchange exchange = new Exchange(request, Origin.REMOTE, mock(Executor.class)); resource.handleRequest(exchange); verify(tracer).buildSpan(eq(Code.POST.toString())); verify(spanBuilder).withTag(eq(Tags.SPAN_KIND.getKey()), eq(Tags.SPAN_KIND_SERVER.toString())); verify(spanBuilder).addReference(eq(References.CHILD_OF), eq(extractedContext)); }
@Test public void testExtractFromEmptyOptionSet() { final Request request = new Request(Code.POST); final Exchange exchange = new Exchange(request, Origin.REMOTE, mock(Executor.class)); resource.handleRequest(exchange); verify(tracer, never()).extract(eq(Format.Builtin.BINARY), any(Binary.class)); verify(tracer).buildSpan(eq(Code.POST.toString())); verify(spanBuilder).withTag(eq(Tags.SPAN_KIND.getKey()), eq(Tags.SPAN_KIND_SERVER.toString())); verify(spanBuilder).addReference(eq(References.CHILD_OF), isNull()); }
@Test public void testApplyTenantTraceSamplingPriority() { final TenantObject tenantObject = TenantObject.from(TENANT_ID, true); final TenantTracingConfig tracingConfig = new TenantTracingConfig(); tracingConfig.setSamplingMode(TracingSamplingMode.NONE); tenantObject.setTracingConfig(tracingConfig); when(tenantClient.get(anyString(), (SpanContext) any())).thenReturn(Future.succeededFuture(tenantObject)); final Request request = new Request(Code.POST); final Exchange exchange = new Exchange(request, Origin.REMOTE, mock(Executor.class)); resource.handleRequest(exchange); verify(tracer).buildSpan(eq(Code.POST.toString())); verify(spanBuilder).withTag(eq(Tags.SPAN_KIND.getKey()), eq(Tags.SPAN_KIND_SERVER.toString())); verify(spanBuilder).addReference(eq(References.CHILD_OF), isNull()); verify(span).setTag(eq(Tags.SAMPLING_PRIORITY.getKey()), eq(0)); verify(span).setBaggageItem(eq(Tags.SAMPLING_PRIORITY.getKey()), eq("0")); }
@Test public void testApplyTenantTraceSamplingPrioritySetForAuthId() { final TenantObject tenantObject = TenantObject.from(TENANT_ID, true); final TenantTracingConfig tracingConfig = new TenantTracingConfig(); tracingConfig.setSamplingModePerAuthId(Map.of(AUTH_ID, TracingSamplingMode.ALL)); tenantObject.setTracingConfig(tracingConfig); when(tenantClient.get(anyString(), (SpanContext) any())).thenReturn(Future.succeededFuture(tenantObject)); final Request request = new Request(Code.POST); final Exchange exchange = new Exchange(request, Origin.REMOTE, mock(Executor.class)); resource.handleRequest(exchange); verify(tracer).buildSpan(eq(Code.POST.toString())); verify(spanBuilder).withTag(eq(Tags.SPAN_KIND.getKey()), eq(Tags.SPAN_KIND_SERVER.toString())); verify(spanBuilder).addReference(eq(References.CHILD_OF), isNull()); verify(span).setTag(eq(Tags.SAMPLING_PRIORITY.getKey()), eq(1)); verify(span).setBaggageItem(eq(Tags.SAMPLING_PRIORITY.getKey()), eq("1")); }