This is an automated email from the ASF dual-hosted git repository. jamesnetherton pushed a commit to branch camel-3.4.x in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/camel-3.4.x by this push: new 7902d06 CAMEL-15277: Fix issues with OpenAPI Java not handling non-default API context paths 7902d06 is described below commit 7902d0629caf644c444b864865d071e9363a89cb Author: James Netherton <jamesnether...@gmail.com> AuthorDate: Wed Jul 8 06:31:18 2020 +0100 CAMEL-15277: Fix issues with OpenAPI Java not handling non-default API context paths --- components/camel-openapi-java/pom.xml | 5 + .../apache/camel/openapi/RestOpenApiProcessor.java | 4 +- .../camel/openapi/RestOpenApiProcessorTest.java | 279 +++++++++++++++++++++ 3 files changed, 287 insertions(+), 1 deletion(-) diff --git a/components/camel-openapi-java/pom.xml b/components/camel-openapi-java/pom.xml index c47c26c..0a308c2 100644 --- a/components/camel-openapi-java/pom.xml +++ b/components/camel-openapi-java/pom.xml @@ -96,6 +96,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-management</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <scope>test</scope> diff --git a/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiProcessor.java b/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiProcessor.java index ccdfd2c..60fd359 100644 --- a/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiProcessor.java +++ b/components/camel-openapi-java/src/main/java/org/apache/camel/openapi/RestOpenApiProcessor.java @@ -85,7 +85,7 @@ public class RestOpenApiProcessor implements Processor { support.renderCamelContexts(exchange.getContext(), adapter, contextId, contextIdPattern, json, yaml, configuration); } else { String name; - if (ObjectHelper.isNotEmpty(route)) { + if (contextIdListing && ObjectHelper.isNotEmpty(route)) { // first part is the camel context if (route.startsWith("/")) { route = route.substring(1); @@ -98,6 +98,8 @@ public class RestOpenApiProcessor implements Processor { } else { // listing not enabled then get current camel context as the name name = exchange.getContext().getName(); + // prevent route filtering + route = ""; } boolean match = true; diff --git a/components/camel-openapi-java/src/test/java/org/apache/camel/openapi/RestOpenApiProcessorTest.java b/components/camel-openapi-java/src/test/java/org/apache/camel/openapi/RestOpenApiProcessorTest.java new file mode 100644 index 0000000..b697ef6 --- /dev/null +++ b/components/camel-openapi-java/src/test/java/org/apache/camel/openapi/RestOpenApiProcessorTest.java @@ -0,0 +1,279 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 + * + * http://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 org.apache.camel.openapi; + +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.support.DefaultExchange; +import org.junit.Test; + +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.assertTrue; + +public class RestOpenApiProcessorTest { + + @Test + public void testRestOpenApiProcessor() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + rest().get("/foo").description("Foo endpoint").route().log("Hello /foo").endRest() + .post("/bar").description("Bar endpoint").route().log("Hello /foo").endRest(); + } + }); + + RestOpenApiProcessor processor = new RestOpenApiProcessor(null, false, null, context.getRestConfiguration()); + Exchange exchange = new DefaultExchange(context); + processor.process(exchange); + + String json = exchange.getMessage().getBody(String.class); + assertNotNull(json); + assertTrue(json.contains("\"/foo\"")); + assertTrue(json.contains("\"/bar\"")); + assertTrue(json.contains("\"summary\" : \"Foo endpoint\"")); + assertTrue(json.contains("\"summary\" : \"Bar endpoint\"")); + } + + @Test + public void testRestOpenApiProcessorOpenApiJsonPath() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + rest().get("/foo").description("Foo endpoint").route().log("Hello /foo").endRest() + .post("/bar").description("Bar endpoint").route().log("Hello /foo").endRest(); + } + }); + + RestOpenApiProcessor processor = new RestOpenApiProcessor(null, false, null, context.getRestConfiguration()); + Exchange exchange = new DefaultExchange(context); + exchange.getMessage().setHeader(Exchange.HTTP_PATH, "/openapi.json"); + processor.process(exchange); + + String json = exchange.getMessage().getBody(String.class); + assertNotNull(json); + assertEquals("application/json", exchange.getMessage().getHeader(Exchange.CONTENT_TYPE)); + assertTrue(json.contains("\"/foo\"")); + assertTrue(json.contains("\"/bar\"")); + assertTrue(json.contains("\"summary\" : \"Foo endpoint\"")); + assertTrue(json.contains("\"summary\" : \"Bar endpoint\"")); + } + + @Test + public void testRestOpenApiProcessorOpenApiYamlPath() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + rest().get("/foo").description("Foo endpoint").route().log("Hello /foo").endRest() + .post("/bar").description("Bar endpoint").route().log("Hello /foo").endRest(); + } + }); + + RestOpenApiProcessor processor = new RestOpenApiProcessor(null, false, null, context.getRestConfiguration()); + Exchange exchange = new DefaultExchange(context); + exchange.getMessage().setHeader(Exchange.HTTP_PATH, "/openapi.yaml"); + processor.process(exchange); + + String yaml = exchange.getMessage().getBody(String.class); + assertNotNull(yaml); + assertEquals("text/yaml", exchange.getMessage().getHeader(Exchange.CONTENT_TYPE)); + assertTrue(yaml.contains("/foo:")); + assertTrue(yaml.contains("/bar:")); + assertTrue(yaml.contains("summary: \"Foo endpoint\"")); + assertTrue(yaml.contains("summary: \"Bar endpoint\"")); + } + + @Test + public void testRestOpenApiProcessorCustomPath() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + rest().get("/foo").description("Foo endpoint").route().log("Hello /foo").endRest() + .post("/bar").description("Bar endpoint").route().log("Hello /foo").endRest(); + } + }); + + RestOpenApiProcessor processor = new RestOpenApiProcessor(null, false, null, context.getRestConfiguration()); + Exchange exchange = new DefaultExchange(context); + exchange.getMessage().setHeader(Exchange.HTTP_PATH, "/some/custom/path/api.json"); + processor.process(exchange); + + String json = exchange.getMessage().getBody(String.class); + assertNotNull(json); + assertEquals("application/json", exchange.getMessage().getHeader(Exchange.CONTENT_TYPE)); + assertTrue(json.contains("\"/foo\"")); + assertTrue(json.contains("\"/bar\"")); + assertTrue(json.contains("\"summary\" : \"Foo endpoint\"")); + assertTrue(json.contains("\"summary\" : \"Bar endpoint\"")); + } + + @Test + public void testRestOpenApiProcessorAcceptHeaderJson() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + rest().get("/foo").description("Foo endpoint").route().log("Hello /foo").endRest() + .post("/bar").description("Bar endpoint").route().log("Hello /foo").endRest(); + } + }); + + RestOpenApiProcessor processor = new RestOpenApiProcessor(null, false, null, context.getRestConfiguration()); + Exchange exchange = new DefaultExchange(context); + exchange.getMessage().setHeader(Exchange.HTTP_PATH, "/some/custom/path/api"); + exchange.getMessage().setHeader("Accept", "application/json"); + processor.process(exchange); + + String json = exchange.getMessage().getBody(String.class); + assertNotNull(json); + assertEquals("application/json", exchange.getMessage().getHeader(Exchange.CONTENT_TYPE)); + assertTrue(json.contains("\"/foo\"")); + assertTrue(json.contains("\"/bar\"")); + assertTrue(json.contains("\"summary\" : \"Foo endpoint\"")); + assertTrue(json.contains("\"summary\" : \"Bar endpoint\"")); + } + + @Test + public void testRestOpenApiProcessorAcceptHeaderYaml() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + rest().get("/foo").description("Foo endpoint").route().log("Hello /foo").endRest() + .post("/bar").description("Bar endpoint").route().log("Hello /foo").endRest(); + } + }); + + RestOpenApiProcessor processor = new RestOpenApiProcessor(null, false, null, context.getRestConfiguration()); + Exchange exchange = new DefaultExchange(context); + exchange.getMessage().setHeader(Exchange.HTTP_PATH, "/some/custom/path/api"); + exchange.getMessage().setHeader("Accept", "application/yaml"); + processor.process(exchange); + + String yaml = exchange.getMessage().getBody(String.class); + assertNotNull(yaml); + assertEquals("text/yaml", exchange.getMessage().getHeader(Exchange.CONTENT_TYPE)); + assertTrue(yaml.contains("/foo:")); + assertTrue(yaml.contains("/bar:")); + assertTrue(yaml.contains("summary: \"Foo endpoint\"")); + assertTrue(yaml.contains("summary: \"Bar endpoint\"")); + } + + @Test + public void testRestOpenApiProcessorContextIdListingEnabledForDefaultPath() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + rest().get("/foo").description("Foo endpoint").route().log("Hello /foo").endRest() + .post("/bar").description("Bar endpoint").route().log("Hello /foo").endRest(); + } + }); + + context.getRegistry().bind("dummy", new DummyRestConsumerFactory()); + + RestOpenApiProcessor processor = new RestOpenApiProcessor(".*camel.*", true, null, context.getRestConfiguration()); + Exchange exchange = new DefaultExchange(context); + exchange.getMessage().setHeader(Exchange.HTTP_PATH, "/openapi.json"); + + context.start(); + try { + processor.process(exchange); + + String json = exchange.getMessage().getBody(String.class); + assertNotNull(json); + + assertEquals("[{\"name\":\"" + context.getName() + "\"}]", json.replaceAll("\\s+", "")); + } finally { + context.stop(); + } + } + + @Test + public void testRestOpenApiProcessorContextIdListingForNamePlaceholder() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + rest().get("/foo").description("Foo endpoint").route().log("Hello /foo").endRest() + .post("/bar").description("Bar endpoint").route().log("Hello /foo").endRest(); + } + }); + + RestOpenApiProcessor processor = new RestOpenApiProcessor("#name#", false, null, context.getRestConfiguration()); + Exchange exchange = new DefaultExchange(context); + exchange.getMessage().setHeader(Exchange.HTTP_PATH, "/openapi.json"); + processor.process(exchange); + + String json = exchange.getMessage().getBody(String.class); + assertNotNull(json); + assertTrue(json.contains("\"/foo\"")); + assertTrue(json.contains("\"/bar\"")); + assertTrue(json.contains("\"summary\" : \"Foo endpoint\"")); + assertTrue(json.contains("\"summary\" : \"Bar endpoint\"")); + } + + @Test + public void testRestOpenApiProcessorContextIdListingEnabledForCustomPath() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + rest("/rest").get("/foo").description("Foo endpoint").route().id("foo-route").log("Hello /foo").endRest() + .post("/bar").description("Bar endpoint").route().id("bar-route").log("Hello /foo").endRest(); + } + }); + + RestOpenApiProcessor processor = new RestOpenApiProcessor(".*camel.*", true, null, context.getRestConfiguration()); + Exchange exchange = new DefaultExchange(context); + exchange.getMessage().setHeader(Exchange.HTTP_PATH, "/" + context.getName() + "/rest"); + processor.process(exchange); + + String json = exchange.getMessage().getBody(String.class); + assertNotNull(json); + assertTrue(json.contains("\"/rest/foo\"")); + assertTrue(json.contains("\"/rest/bar\"")); + assertTrue(json.contains("\"summary\" : \"Foo endpoint\"")); + assertTrue(json.contains("\"summary\" : \"Bar endpoint\"")); + } + + @Test + public void testRestOpenApiProcessorContextIdPatternNoMatches() throws Exception { + CamelContext context = new DefaultCamelContext(); + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + rest("/").get("/foo").description("Foo endpoint").route().log("Hello /foo").endRest().post("/bar").description("Bar endpoint").route().log("Hello /foo").endRest(); + } + }); + + RestOpenApiProcessor processor = new RestOpenApiProcessor("an-invalid-pattern", false, null, context.getRestConfiguration()); + Exchange exchange = new DefaultExchange(context); + exchange.getMessage().setHeader("/some/rest/api/document.json", Exchange.HTTP_PATH); + processor.process(exchange); + + assertEquals(204, exchange.getMessage().getHeader(Exchange.HTTP_RESPONSE_CODE)); + assertNull(exchange.getMessage().getBody()); + } +}