From 17ef05d78f9a80c2a420dff28a799a7911232411 Mon Sep 17 00:00:00 2001 From: Staffan Olsson Date: Sun, 13 Dec 2020 06:48:56 +0100 Subject: [PATCH 1/2] Adds a test for new paths we need to support --- .../KafkaHookResourceIntegrationTest.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/rest/src/test/java/se/yolean/kafka/hook/rest/KafkaHookResourceIntegrationTest.java b/rest/src/test/java/se/yolean/kafka/hook/rest/KafkaHookResourceIntegrationTest.java index 0b70b1d..a52bff8 100644 --- a/rest/src/test/java/se/yolean/kafka/hook/rest/KafkaHookResourceIntegrationTest.java +++ b/rest/src/test/java/se/yolean/kafka/hook/rest/KafkaHookResourceIntegrationTest.java @@ -29,6 +29,7 @@ import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.CoreMatchers.not; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import java.io.UnsupportedEncodingException; import java.time.Duration; @@ -160,6 +161,44 @@ public void testProduceString() throws UnsupportedEncodingException { assertEquals("github.com/Yolean/kafka-hook/mytype", headers(record2).get("ce_type")); } + @Test + public void testProduceAlternativeUrls() throws UnsupportedEncodingException { + given() + .contentType(ContentType.TEXT) + .accept(ContentType.JSON) + .body("test1".getBytes()) + .when().post("/hook/v1/mytype/with/slashes") + .then() + .body(containsString("\"offset\":" + (startOffset))) + .statusCode(200); + given() + .contentType(ContentType.TEXT) + .accept(ContentType.JSON) + .body("test2".getBytes()) + .when().post("/some-prefix/v1/hook") + .then() + .body(containsString("\"offset\":" + (startOffset + 1))) + .statusCode(200); + given() + .contentType(ContentType.TEXT) + .accept(ContentType.JSON) + .body("test3".getBytes()) + .when().post("/some-prefix/v1/hook/sub/type/") + .then() + .body(containsString("\"offset\":" + (startOffset + 2))) + .statusCode(200); + waitBetweenPolls(); + ConsumerRecords records = consumer.poll(Duration.ofMillis(1000)); + Iterator> it = records.iterator(); + ConsumerRecord record1 = it.next(); + assertEquals("github.com/Yolean/kafka-hook/mytype/with/slashes", headers(record1).get("ce_type")); + ConsumerRecord record2 = it.next(); + assertEquals("github.com/Yolean/kafka-hook/", headers(record2).get("ce_type")); + ConsumerRecord record3 = it.next(); + assertNotEquals("github.com/Yolean/kafka-hook/sub/type/", headers(record3).get("ce_type")); + assertEquals("github.com/Yolean/kafka-hook/sub/type", headers(record3).get("ce_type")); + } + @Test public void testCloudeventsDistributedTracingExtensionWithEnvoyHeaders() { given() From ecc619a4c06356f43fa3d80ffdb6d1d475e22148 Mon Sep 17 00:00:00 2001 From: Staffan Olsson Date: Sat, 12 Dec 2020 21:35:27 +0100 Subject: [PATCH 2/2] Adds support for routing to hook as part of an api group Could have been done with rewrites, but kafka-hook's design goal of capturing all requests hint that we should be less strict on path. Can't catch everything without interpretation though, because if there's no versioning we won't be able to evolve the mapping to produced messages. --- .../hook/rest/KafkaHookRestResource.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/rest/src/main/java/se/yolean/kafka/hook/rest/KafkaHookRestResource.java b/rest/src/main/java/se/yolean/kafka/hook/rest/KafkaHookRestResource.java index 95ade98..32e0bb4 100644 --- a/rest/src/main/java/se/yolean/kafka/hook/rest/KafkaHookRestResource.java +++ b/rest/src/main/java/se/yolean/kafka/hook/rest/KafkaHookRestResource.java @@ -17,20 +17,35 @@ import se.yolean.kafka.hook.http.KafkaHookResource; @Produces(MediaType.APPLICATION_JSON) -@Path("/hook/v1") +@Path("/") public class KafkaHookRestResource { @Inject KafkaHookResource hook; @POST - public Response produce(@Context HttpHeaders headers, @Context UriInfo uri, InputStream payload) throws IOException { + @Path("hook/v1") + public Response produce(@Context HttpHeaders headers, @Context UriInfo uri, InputStream payload) + throws IOException { return hook.produce(headers, uri, "", payload); } @POST - @Path("/{type}") + @Path("hook/v1/{type:.*}") public Response produce(@Context HttpHeaders headers, @Context UriInfo uri, @PathParam("type") String type, InputStream payload) - // if we fail to read the payload, which would be very strange + throws IOException { + return hook.produce(headers, uri, type, payload); + } + + @POST + @Path("{prefix}/v1/hook") + public Response produceAltPathWithoutType(@Context HttpHeaders headers, @Context UriInfo uri, InputStream payload) + throws IOException { + return hook.produce(headers, uri, "", payload); + } + + @POST + @Path("{prefix}/v1/hook/{type:.*}") + public Response produceAltPath(@Context HttpHeaders headers, @Context UriInfo uri, @PathParam("type") String type, InputStream payload) throws IOException { return hook.produce(headers, uri, type, payload); }