Skip to content

[CI Pipeline] Released Snapshot version: 8.0.7-alpha-169-SNAPSHOT #352

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<groupId>com.uid2</groupId>
<artifactId>uid2-shared</artifactId>
<version>8.0.6</version>
<version>8.0.7-alpha-169-SNAPSHOT</version>
<name>${project.groupId}:${project.artifactId}</name>
<description>Library for all the shared uid2 operations</description>
<url>https://github.com/IABTechLab/uid2docs</url>
Expand Down
30 changes: 26 additions & 4 deletions src/main/java/com/uid2/shared/vertx/RequestCapturingHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.uid2.shared.auth.IAuthorizable;
import com.uid2.shared.jmx.AdminApi;
import com.uid2.shared.middleware.AuthMiddleware;
import com.uid2.shared.model.Site;
import com.uid2.shared.store.ISiteStore;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.Metrics;
import io.vertx.core.Handler;
Expand Down Expand Up @@ -32,11 +34,21 @@ public class RequestCapturingHandler implements Handler<RoutingContext> {
private Queue<String> _capturedRequests = null;
private final Map<String, Counter> _apiMetricCounters = new HashMap<>();
private final Map<String, Counter> _clientAppVersionCounters = new HashMap<>();
private ISiteStore siteStore;

private static String formatRFC1123DateTime(long time) {
return DateTimeFormatter.RFC_1123_DATE_TIME.format(Instant.ofEpochMilli(time).atZone(ZONE_GMT));
}

public RequestCapturingHandler()
{
}

public RequestCapturingHandler(ISiteStore siteStore)
{
this.siteStore = siteStore;
}

@Override
public void handle(RoutingContext context) {
if (!AdminApi.instance.getCaptureRequests() && !AdminApi.instance.getPublishApiMetrics()) {
Expand Down Expand Up @@ -105,7 +117,17 @@ private void capture(RoutingContext context, long timestamp, String remoteClient
}

final Integer siteId = getSiteId(context);
incrementMetricCounter(apiContact, siteId, host, status, method, path);

String siteName = "unknown";
if (siteId != null && siteStore != null) {
Site site = siteStore.getSite(siteId);
if (site != null)
{
siteName = site.getName();
}
}

incrementMetricCounter(apiContact, siteId, siteName, host, status, method, path);

if (request.headers().contains(Const.Http.AppVersionHeader)) {
incrementAppVersionCounter(apiContact, request.headers().get(Const.Http.AppVersionHeader));
Expand Down Expand Up @@ -196,14 +218,14 @@ private static Integer getSiteId(RoutingContext context) {
return null;
}

private void incrementMetricCounter(String apiContact, Integer siteId, String host, int status, HttpMethod method, String path) {
private void incrementMetricCounter(String apiContact, Integer siteId, String siteName, String host, int status, HttpMethod method, String path) {
assert apiContact != null;
String key = apiContact + "|" + siteId + "|" + host + "|" + status + "|" + method.name() + "|" + path;
String key = apiContact + "|" + siteId + "|" + siteName + "|" + host + "|" + status + "|" + method.name() + "|" + path;
if (!_apiMetricCounters.containsKey(key)) {
Counter counter = Counter
.builder("uid2.http_requests")
.description("counter for how many http requests are processed per each api contact and status code")
.tags("api_contact", apiContact, "site_id", String.valueOf(siteId), "host", host, "status", String.valueOf(status), "method", method.name(), "path", path)
.tags("api_contact", apiContact, "site_id", String.valueOf(siteId), "site_name", siteName, "host", host, "status", String.valueOf(status), "method", method.name(), "path", path)
.register(Metrics.globalRegistry);
_apiMetricCounters.put(key, counter);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.uid2.shared.auth.ClientKey;
import com.uid2.shared.auth.OperatorKey;
import com.uid2.shared.middleware.AuthMiddleware;
import com.uid2.shared.model.Site;
import com.uid2.shared.store.ISiteStore;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import io.vertx.core.Handler;
Expand All @@ -14,35 +16,50 @@
import io.vertx.ext.web.client.WebClient;
import io.vertx.junit5.VertxExtension;
import io.vertx.junit5.VertxTestContext;
import org.assertj.core.condition.AnyOf;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.mockito.Mock;
import org.mockito.Mockito;

import java.time.Instant;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;

import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when;

@ExtendWith(VertxExtension.class)
public class RequestCapturingHandlerTest {
private static final int Port = 8080;
private static final Handler<RoutingContext> dummyResponseHandler = routingContext -> {
routingContext.response().setStatusCode(200).end();
};

private ISiteStore siteStore;

@BeforeEach
public void before() {
Metrics.globalRegistry.forEachMeter(Metrics.globalRegistry::remove);
Metrics.globalRegistry.add(new SimpleMeterRegistry());

Site site100 = new Site(100, "test-100", true);
Site site200 = new Site(200, "test-200", true);
siteStore = Mockito.mock(ISiteStore.class);
when(siteStore.getSite(100)).thenReturn(site100);
when(siteStore.getSite(200)).thenReturn(site200);
}

@Test
public void captureSimplePath(Vertx vertx, VertxTestContext testContext) {
Router router = Router.router(vertx);
router.route().handler(new RequestCapturingHandler());
router.route().handler(new RequestCapturingHandler(siteStore));
router.get("/v1/token/generate").handler(dummyResponseHandler);

vertx.createHttpServer().requestHandler(router).listen(Port, testContext.succeeding(id -> {
Expand Down Expand Up @@ -112,7 +129,7 @@ public void captureStaticPath(Vertx vertx, VertxTestContext testContext) {
@Test
public void captureUnknownPath(Vertx vertx, VertxTestContext testContext) {
Router router = Router.router(vertx);
router.route().handler(new RequestCapturingHandler());
router.route().handler(new RequestCapturingHandler(siteStore));

vertx.createHttpServer().requestHandler(router).listen(Port, testContext.succeeding(id -> {
WebClient client = WebClient.create(vertx);
Expand All @@ -132,9 +149,9 @@ public void captureUnknownPath(Vertx vertx, VertxTestContext testContext) {

@ParameterizedTest
@MethodSource("siteIdRoutingContextData")
public void getSiteIdFromRoutingContextData(String key, Object value, String siteId, Vertx vertx, VertxTestContext testContext) {
public void getSiteIdFromRoutingContextData(String key, Object value, String siteId, String siteName, Vertx vertx, VertxTestContext testContext) {
Router router = Router.router(vertx);
router.route().handler(new RequestCapturingHandler());
router.route().handler(new RequestCapturingHandler(siteStore));
router.get("/test").handler(ctx -> {
if (key != null) {
ctx.put(key, value);
Expand All @@ -149,6 +166,7 @@ public void getSiteIdFromRoutingContextData(String key, Object value, String sit
double actual = Metrics.globalRegistry
.get("uid2.http_requests")
.tag("site_id", siteId)
.tag("site_name", siteName)
.counter()
.count();
Assertions.assertEquals(1, actual);
Expand All @@ -160,11 +178,11 @@ public void getSiteIdFromRoutingContextData(String key, Object value, String sit
private static Stream<Arguments> siteIdRoutingContextData() {
// Arguments are: routing context data key, routing context data value, site ID tag.
return Stream.of(
Arguments.of(Const.RoutingContextData.SiteId, 100, "100"),
Arguments.of(AuthMiddleware.API_CLIENT_PROP, new ClientKey("keyHash", "keySalt", "secret", "", Instant.MIN, Set.of(), 200, "test-key-id-1"), "200"),
Arguments.of(AuthMiddleware.API_CLIENT_PROP, new OperatorKey("test-keyHash", "test-keySalt", "name", "contact", "protocol", 0, false, "test-key-id-2"), "null"),
Arguments.of(AuthMiddleware.API_CLIENT_PROP, new OperatorKey("test-keyHash", "test-keySalt", "name", "contact", "protocol", 0, false, 300, "test-key-id-3"), "300"),
Arguments.of(null, null, "null")
Arguments.of(Const.RoutingContextData.SiteId, 100, "100", "test-100"),
Arguments.of(AuthMiddleware.API_CLIENT_PROP, new ClientKey("keyHash", "keySalt", "secret", "", Instant.MIN, Set.of(), 200, "test-key-id-1"), "200", "test-200"),
Arguments.of(AuthMiddleware.API_CLIENT_PROP, new OperatorKey("test-keyHash", "test-keySalt", "name", "contact", "protocol", 0, false, "test-key-id-2"), "null", "unknown"),
Arguments.of(AuthMiddleware.API_CLIENT_PROP, new OperatorKey("test-keyHash", "test-keySalt", "name", "contact", "protocol", 0, false, 300, "test-key-id-3"), "300", "unknown"),
Arguments.of(null, null, "null", "unknown")
);
}
}