From 3ddbc4c43ea6baea590c4478353e01ef06b845f4 Mon Sep 17 00:00:00 2001 From: Szymon Sasin Date: Thu, 10 Aug 2023 13:25:54 +0300 Subject: [PATCH] [Refactoring] RouterService wrapRoutes -> filter --- .../com/mbed/coap/server/RouterService.java | 23 +++------------- .../mbed/coap/server/RouterServiceTest.java | 6 ++--- .../micrometer/MicrometerMetricsFilter.java | 27 +++++++++---------- .../MicrometerMetricsFilterTest.java | 25 ++++++++++++++--- 4 files changed, 41 insertions(+), 40 deletions(-) diff --git a/coap-core/src/main/java/com/mbed/coap/server/RouterService.java b/coap-core/src/main/java/com/mbed/coap/server/RouterService.java index e36bfa54..0c097e15 100644 --- a/coap-core/src/main/java/com/mbed/coap/server/RouterService.java +++ b/coap-core/src/main/java/com/mbed/coap/server/RouterService.java @@ -88,6 +88,7 @@ private Service findHandler(RequestMatcher requestMat public static class RouteBuilder { private final Map> handlers = new HashMap<>(); public Service defaultHandler = NOT_FOUND_SERVICE; + private Filter filter = Filter.identity(); public RouteBuilder get(String uriPath, Service service) { return add(Method.GET, uriPath, service); @@ -122,7 +123,7 @@ public RouteBuilder any(String uriPath, Service servi } private RouteBuilder add(Method method, String uriPath, Service service) { - handlers.put(new RequestMatcher(method, uriPath), service); + handlers.put(new RequestMatcher(method, uriPath), filter.then(service)); return this; } @@ -137,31 +138,15 @@ public RouteBuilder mergeRoutes(RouteBuilder otherBuilder) { return this; } - public RouteBuilder wrapRoutes(WrapFilterProducer wrapperFilterProducer) { - Map> wrappedRouteHandlers = new HashMap<>(); - for (Entry> e : handlers.entrySet()) { - RequestMatcher key = e.getKey(); - Service service = e.getValue(); - - wrappedRouteHandlers.put(key, wrapperFilterProducer.getFilter(key.method, key.uriPath).then(service)); - } - handlers.putAll(wrappedRouteHandlers); + public RouteBuilder filter(Filter wrapperFilterProducer) { + this.filter = this.filter.andThen(wrapperFilterProducer); return this; } - public RouteBuilder wrapRoutes(Filter wrapperFilter) { - return wrapRoutes((WrapFilterProducer) (m, u) -> wrapperFilter); - } - public Service build() { return new RouterService(handlers, defaultHandler); } - - @FunctionalInterface - public interface WrapFilterProducer { - Filter getFilter(Method method, String uriPath); - } } static final class RequestMatcher { diff --git a/coap-core/src/test/java/com/mbed/coap/server/RouterServiceTest.java b/coap-core/src/test/java/com/mbed/coap/server/RouterServiceTest.java index bb7cbc97..f2c6d926 100644 --- a/coap-core/src/test/java/com/mbed/coap/server/RouterServiceTest.java +++ b/coap-core/src/test/java/com/mbed/coap/server/RouterServiceTest.java @@ -45,13 +45,13 @@ public void shouldBuildSimpleService() throws ExecutionException, InterruptedExc } @Test - public void shouldWrapRoutes() throws ExecutionException, InterruptedException { + public void shouldFilterRoutes() throws ExecutionException, InterruptedException { Service svc = RouterService.builder() + .get("/test3", simpleHandler) + .filter((CoapRequest req, Service nextSvc) -> CompletableFuture.completedFuture(ok("42"))) .get("/test1", simpleHandler) .post("/test1", simpleHandler) .get("/test2/*", simpleHandler) - .wrapRoutes((CoapRequest req, Service nextSvc) -> CompletableFuture.completedFuture(ok("42"))) - .get("/test3", simpleHandler) .build(); assertEquals("42", svc.apply(CoapRequest.get("/test1")).get().getPayloadString()); diff --git a/coap-metrics/src/main/java/org/opencoap/coap/metrics/micrometer/MicrometerMetricsFilter.java b/coap-metrics/src/main/java/org/opencoap/coap/metrics/micrometer/MicrometerMetricsFilter.java index 74307a00..038cc80b 100644 --- a/coap-metrics/src/main/java/org/opencoap/coap/metrics/micrometer/MicrometerMetricsFilter.java +++ b/coap-metrics/src/main/java/org/opencoap/coap/metrics/micrometer/MicrometerMetricsFilter.java @@ -29,20 +29,21 @@ import java.util.Arrays; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.function.Function; public class MicrometerMetricsFilter implements Filter.SimpleFilter { private final MeterRegistry registry; private final String metricName; - private final String route; + private final Function resolveRoute; public static MicrometerMetricsFilterBuilder builder() { return new MicrometerMetricsFilterBuilder(); } - MicrometerMetricsFilter(MeterRegistry registry, String metricName, DistributionStatisticConfig distributionStatisticConfig, String route) { + MicrometerMetricsFilter(MeterRegistry registry, String metricName, DistributionStatisticConfig distributionStatisticConfig, Function resolveRoute) { this.registry = registry; this.metricName = metricName; - this.route = route; + this.resolveRoute = resolveRoute; registry.config().meterFilter(new MeterFilter() { @Override @@ -67,21 +68,19 @@ public CompletableFuture apply(CoapRequest req, Service requestTags(CoapRequest req, CoapResponse resp, Throwable err) { - String uriPath = req.options().getUriPath(); return Arrays.asList( Tag.of("method", req.getMethod().name()), Tag.of("status", resp != null ? resp.getCode().codeToString() : "n/a"), - Tag.of("route", getRoute(uriPath)), + Tag.of("route", getRoute(req)), Tag.of("throwable", err != null ? err.getClass().getCanonicalName() : "n/a") ); } - private String getRoute(String uriPath) { - if (route != null) { - return route; - } + private String getRoute(CoapRequest req) { + String uriPath = req.options().getUriPath(); + uriPath = uriPath != null ? uriPath : "/"; - return uriPath != null ? uriPath : "/"; + return resolveRoute.apply(uriPath); } public static class MicrometerMetricsFilterBuilder { @@ -89,7 +88,7 @@ public static class MicrometerMetricsFilterBuilder { private MeterRegistry registry; private String metricName; private DistributionStatisticConfig distributionStatisticConfig; - private String route; + private Function resolveRoute = Function.identity(); MicrometerMetricsFilterBuilder() { } @@ -109,8 +108,8 @@ public MicrometerMetricsFilterBuilder distributionStatisticConfig(DistributionSt return this; } - public MicrometerMetricsFilterBuilder route(String route) { - this.route = route; + public MicrometerMetricsFilterBuilder resolveRoute(Function resolveRoute) { + this.resolveRoute = resolveRoute; return this; } @@ -127,7 +126,7 @@ public MicrometerMetricsFilter build() { this.distributionStatisticConfig = DistributionStatisticConfig.builder().percentiles(0.5, 0.9, 0.95, 0.99).build(); } - return new MicrometerMetricsFilter(this.registry, this.metricName, this.distributionStatisticConfig, this.route); + return new MicrometerMetricsFilter(this.registry, this.metricName, this.distributionStatisticConfig, resolveRoute); } } } diff --git a/coap-metrics/src/test/java/org/opencoap/coap/metrics/micrometer/MicrometerMetricsFilterTest.java b/coap-metrics/src/test/java/org/opencoap/coap/metrics/micrometer/MicrometerMetricsFilterTest.java index dcdad986..61bf59d8 100644 --- a/coap-metrics/src/test/java/org/opencoap/coap/metrics/micrometer/MicrometerMetricsFilterTest.java +++ b/coap-metrics/src/test/java/org/opencoap/coap/metrics/micrometer/MicrometerMetricsFilterTest.java @@ -19,17 +19,19 @@ import static com.mbed.coap.packet.CoapResponse.ok; import static com.mbed.coap.utils.FutureHelpers.failedFuture; import static java.util.concurrent.CompletableFuture.completedFuture; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; import com.mbed.coap.packet.CoapRequest; import com.mbed.coap.packet.CoapResponse; import com.mbed.coap.utils.Service; import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.distribution.DistributionStatisticConfig; -import io.micrometer.core.instrument.logging.LoggingMeterRegistry; import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import java.util.concurrent.ExecutionException; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; class MicrometerMetricsFilterTest { private final MeterRegistry registry = new SimpleMeterRegistry(); @@ -95,10 +97,21 @@ public void shouldRegisterTimerMetric() { @Test public void shouldUseDefinedRouteForAllMeteredRequests() { - MicrometerMetricsFilter filterWithRoute = MicrometerMetricsFilter.builder().registry(registry).route("/test/DEVICE_ID").build(); + MicrometerMetricsFilter filterWithRoute = MicrometerMetricsFilter.builder() + .resolveRoute(uriPath -> { + if (uriPath.startsWith("/test/")) { + return "/test/DEVICE_ID"; + } + + return uriPath; + }) + .registry(registry) + .build(); + Service svc = filterWithRoute.then(__ -> completedFuture(ok("OK"))); svc.apply(get("/test/1")).join(); svc.apply(get("/test/2")).join(); + svc.apply(get("/hello")).join(); assertNull( registry.find("coap.server.requests") @@ -114,5 +127,9 @@ public void shouldUseDefinedRouteForAllMeteredRequests() { .tag("route", "/test/DEVICE_ID") .timer().count() ); + assertEquals(1, registry.find("coap.server.requests") + .tag("route", "/hello") + .timer().count() + ); } }