Skip to content

Commit

Permalink
Added RestEasy server and client examples
Browse files Browse the repository at this point in the history
modified the jakarta imports to have both jakarta and javax imports on the classpath. Added filters for client and server side that use jakarta imports and added RestEasy tests for client and server
  • Loading branch information
marcingrzejszczak committed Aug 22, 2023
1 parent 2b15312 commit 1e8f194
Show file tree
Hide file tree
Showing 13 changed files with 490 additions and 55 deletions.
3 changes: 3 additions & 0 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ def VERSIONS = [
'org.hsqldb:hsqldb:2.5.+', // 2.6.0 requires JDK 11.
'org.jooq:jooq:3.14.+',
'org.jsr107.ri:cache-ri-impl:1.0.0',
'org.jboss.resteasy:resteasy-client:6.2.4.Final',
'org.jboss.resteasy:resteasy-netty4:6.2.4.Final',
'javax.validation:validation-api:1.0.0.GA',
'org.latencyutils:LatencyUtils:latest.release',
'org.mockito:mockito-core:5.+', // 5.x requires JDK 11.
'org.mockito:mockito-inline:5.+',
Expand Down
5 changes: 5 additions & 0 deletions micrometer-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ jar {
dependencies {
api project(":micrometer-commons")
api project(":micrometer-observation")
optionalApi 'javax.ws.rs:javax.ws.rs-api:2.+' // javax
optionalApi 'jakarta.ws.rs:jakarta.ws.rs-api:3.+' // jakarta

java11Api project(":micrometer-commons")
java11Api project(":micrometer-observation")
Expand Down Expand Up @@ -200,6 +202,9 @@ dependencies {
// gRPC
testImplementation("io.grpc:grpc-core")
testImplementation("io.grpc:grpc-testing-proto")
testImplementation("javax.validation:validation-api")
testImplementation("org.jboss.resteasy:resteasy-netty4")
testImplementation("org.jboss.resteasy:resteasy-netty4")
}

task shenandoahTest(type: Test) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
package io.micrometer.core.instrument.binder.http;

import java.net.URI;
import java.util.regex.Pattern;

import io.micrometer.common.KeyValue;
import io.micrometer.common.KeyValues;
import io.micrometer.common.lang.Nullable;
Expand All @@ -23,9 +26,6 @@
import io.micrometer.core.instrument.binder.http.HttpObservationDocumentation.CommonHighCardinalityKeys;
import io.micrometer.core.instrument.binder.http.HttpObservationDocumentation.CommonLowCardinalityKeys;

import java.net.URI;
import java.util.regex.Pattern;

class AbstractDefaultHttpClientRequestObservationConvention {

private static final Pattern PATTERN_BEFORE_PATH = Pattern.compile("^https?://[^/]+/");
Expand All @@ -36,10 +36,6 @@ class AbstractDefaultHttpClientRequestObservationConvention {

private static final KeyValue STATUS_CLIENT_ERROR = KeyValue.of(CommonLowCardinalityKeys.STATUS, "CLIENT_ERROR");

private static final KeyValue HTTP_OUTCOME_SUCCESS = KeyValue.of(CommonLowCardinalityKeys.OUTCOME, "SUCCESS");

private static final KeyValue HTTP_OUTCOME_UNKNOWN = KeyValue.of(CommonLowCardinalityKeys.OUTCOME, "UNKNOWN");

private static final KeyValue CLIENT_NAME_NONE = KeyValue.of(ClientLowCardinalityKeys.CLIENT_NAME,
KeyValue.NONE_VALUE);

Expand Down Expand Up @@ -106,9 +102,9 @@ private KeyValue exception(@Nullable Throwable error) {

private KeyValue outcome(@Nullable Integer statusCode) {
if (statusCode != null) {
return HttpOutcome.forStatus(statusCode);
return HttpOutcome.forStatus(false, statusCode);
}
return HTTP_OUTCOME_UNKNOWN;
return HttpOutcome.forStatus(false, statusCode);
}

protected KeyValues getHighCardinalityKeyValues(@Nullable URI uri, @Nullable String userAgent) {
Expand All @@ -131,17 +127,4 @@ private KeyValue userAgent(@Nullable String userAgent) {
return USER_AGENT_NONE;
}

static class HttpOutcome {

static KeyValue forStatus(int statusCode) {
if (statusCode >= 200 && statusCode < 300) {
return HTTP_OUTCOME_SUCCESS;
}
else {
return HTTP_OUTCOME_UNKNOWN;
}
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ private KeyValue exception(@Nullable Throwable error) {

private KeyValue outcome(@Nullable Integer status) {
if (status != null) {
return HttpOutcome.forStatus(status);
return HttpOutcome.forStatus(true, status);
}
return HTTP_OUTCOME_UNKNOWN;
}
Expand All @@ -141,17 +141,4 @@ private KeyValue httpUrl(@Nullable String requestUri) {
return HTTP_URL_UNKNOWN;
}

static class HttpOutcome {

static KeyValue forStatus(int statusCode) {
if (statusCode >= 200 && statusCode < 300) {
return HTTP_OUTCOME_SUCCESS;
}
else {
return HTTP_OUTCOME_UNKNOWN;
}
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
public class DefaultHttpJakartaClientRequestObservationConvention extends
AbstractDefaultHttpClientRequestObservationConvention implements HttpJakartaClientRequestObservationConvention {

public static DefaultHttpJakartaClientRequestObservationConvention INSTANCE = new DefaultHttpJakartaClientRequestObservationConvention();

private static final String DEFAULT_NAME = "http.client.requests";

private final String name;
Expand Down Expand Up @@ -62,7 +64,7 @@ public String getContextualName(HttpJakartaClientRequestObservationContext conte

@Override
public KeyValues getLowCardinalityKeyValues(HttpJakartaClientRequestObservationContext context) {
URI uri = context.getCarrier() != null ? context.getCarrier().getUriInfo().getRequestUri() : null;
URI uri = context.getCarrier() != null ? context.getCarrier().getUri() : null;
Throwable throwable = context.getError();
String methodName = context.getCarrier() != null ? context.getCarrier().getMethod() : null;
Integer statusCode = context.getResponse() != null ? context.getResponse().getStatus() : null;
Expand All @@ -72,7 +74,7 @@ public KeyValues getLowCardinalityKeyValues(HttpJakartaClientRequestObservationC

@Override
public KeyValues getHighCardinalityKeyValues(HttpJakartaClientRequestObservationContext context) {
URI uri = context.getCarrier() != null ? context.getCarrier().getUriInfo().getRequestUri() : null;
URI uri = context.getCarrier() != null ? context.getCarrier().getUri() : null;
String userAgent = context.getCarrier() != null ? context.getCarrier().getHeaderString("User-Agent") : null;
return getHighCardinalityKeyValues(uri, userAgent);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
public class DefaultHttpJakartaServerRequestObservationConvention extends
AbstractDefaultHttpServerRequestObservationConvention implements HttpJakartaServerRequestObservationConvention {

public static DefaultHttpJakartaServerRequestObservationConvention INSTANCE = new DefaultHttpJakartaServerRequestObservationConvention();

private static final String DEFAULT_NAME = "http.server.requests";

private final String name;
Expand Down Expand Up @@ -61,13 +63,15 @@ public KeyValues getLowCardinalityKeyValues(HttpJakartaServerRequestObservationC
String method = context.getCarrier() != null ? context.getCarrier().getMethod() : null;
Integer status = context.getResponse() != null ? context.getResponse().getStatus() : null;
String pathPattern = context.getPathPattern();
String requestUri = context.getCarrier() != null ? context.getCarrier().getRequestURI() : null;
String requestUri = context.getCarrier() != null ? context.getCarrier().getUriInfo().getRequestUri().toString()
: null;
return getLowCardinalityKeyValues(context.getError(), method, status, pathPattern, requestUri);
}

@Override
public KeyValues getHighCardinalityKeyValues(HttpJakartaServerRequestObservationContext context) {
String requestUri = context.getCarrier() != null ? context.getCarrier().getRequestURI() : null;
String requestUri = context.getCarrier() != null ? context.getCarrier().getUriInfo().getRequestUri().toString()
: null;
return getHighCardinalityKeyValues(requestUri);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2020 VMware, Inc.
* Copyright 2023 VMware, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,10 +17,8 @@

import io.micrometer.common.lang.Nullable;
import io.micrometer.observation.transport.RequestReplySenderContext;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import jakarta.ws.rs.client.ClientRequestContext;
import jakarta.ws.rs.client.ClientResponseContext;

/**
* Context that holds information for metadata collection during the client HTTP exchanges
Expand All @@ -34,21 +32,21 @@
* @since 1.12.0
*/
public class HttpJakartaClientRequestObservationContext
extends RequestReplySenderContext<ContainerRequestContext, ContainerResponseContext> {
extends RequestReplySenderContext<ClientRequestContext, ClientResponseContext> {

@Nullable
private String uriTemplate;

/**
* Create an observation context for HTTP client observations.
* @param containerRequestContext the context for a {@link ContainerRequestFilter}
* @param containerRequestContext the context for a {@link ClientRequestContext}
*/
public HttpJakartaClientRequestObservationContext(ContainerRequestContext containerRequestContext) {
public HttpJakartaClientRequestObservationContext(ClientRequestContext containerRequestContext) {
super(HttpJakartaClientRequestObservationContext::setRequestHeader);
this.setCarrier(containerRequestContext);
}

private static void setRequestHeader(@Nullable ContainerRequestContext context, String name, String value) {
private static void setRequestHeader(@Nullable ClientRequestContext context, String name, String value) {
if (context != null) {
context.getHeaders().add(name, value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

import io.micrometer.common.lang.Nullable;
import io.micrometer.observation.transport.RequestReplyReceiverContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ContainerResponseContext;

/**
* Context that holds information for metadata collection regarding Servlet HTTP requests
Expand All @@ -32,15 +32,14 @@
* @since 1.12.0
*/
public class HttpJakartaServerRequestObservationContext
extends RequestReplyReceiverContext<HttpServletRequest, HttpServletResponse> {
extends RequestReplyReceiverContext<ContainerRequestContext, ContainerResponseContext> {

@Nullable
private String pathPattern;

public HttpJakartaServerRequestObservationContext(HttpServletRequest request, HttpServletResponse response) {
super(HttpServletRequest::getHeader);
public HttpJakartaServerRequestObservationContext(ContainerRequestContext request) {
super(ContainerRequestContext::getHeaderString);
setCarrier(request);
setResponse(response);
}

@Nullable
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright 2023 VMware, Inc.
*
* 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
*
* https://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 io.micrometer.core.instrument.binder.http;

import io.micrometer.common.KeyValue;
import io.micrometer.common.lang.Nullable;
import io.micrometer.core.instrument.binder.http.HttpObservationDocumentation.CommonLowCardinalityKeys;

class HttpOutcome {

static final KeyValue HTTP_OUTCOME_SUCCESS = KeyValue.of(CommonLowCardinalityKeys.OUTCOME, "SUCCESS");

static final KeyValue HTTP_OUTCOME_UNKNOWN = KeyValue.of(CommonLowCardinalityKeys.OUTCOME, "UNKNOWN");

static KeyValue forStatus(boolean server, @Nullable Integer statusCode) {
if (statusCode == null) {
return HTTP_OUTCOME_UNKNOWN;
}
if (statusCode >= 200 && statusCode < 300) {
return HTTP_OUTCOME_SUCCESS;
}
else if (!server) {
Series resolved = Series.resolve(statusCode);
if (resolved == null) {
return HTTP_OUTCOME_UNKNOWN;
}
return KeyValue.of(CommonLowCardinalityKeys.OUTCOME, resolved.name());
}
else {
return HTTP_OUTCOME_UNKNOWN;
}
}

// Taken from Spring Http
enum Series {

INFORMATIONAL(1), SUCCESSFUL(2), REDIRECTION(3), CLIENT_ERROR(4), SERVER_ERROR(5);

private final int value;

Series(int value) {
this.value = value;
}

@Nullable
static Series resolve(int statusCode) {
int seriesCode = statusCode / 100;
for (Series series : values()) {
if (series.value == seriesCode) {
return series;
}
}
return null;
}

}

}
Loading

0 comments on commit 1e8f194

Please sign in to comment.