You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/05/21 07:46:33 UTC

[camel] branch main updated: CAMEL-19364 Rest-openapi: lookup mechanism does not work after changes from Camel-18963 (#10144)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 241da38b0fc CAMEL-19364 Rest-openapi: lookup mechanism does not work after changes from Camel-18963 (#10144)
241da38b0fc is described below

commit 241da38b0fc52b0f6d845ed29bd025b9e8a6a545
Author: JiriOndrusek <on...@gmail.com>
AuthorDate: Sun May 21 09:46:27 2023 +0200

    CAMEL-19364 Rest-openapi: lookup mechanism does not work after changes from Camel-18963 (#10144)
---
 .../rest/openapi/RestOpenApiEndpoint.java          | 39 +++++++++++++++++++---
 .../component/rest/openapi/RestOpenApiBean.java    | 29 ++++++++++++++++
 .../rest/openapi/RestOpenApiComponentTest.java     | 33 +++++++++++++++++-
 3 files changed, 96 insertions(+), 5 deletions(-)

diff --git a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiEndpoint.java b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiEndpoint.java
index 1961b4df715..231bc8eb554 100644
--- a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiEndpoint.java
+++ b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiEndpoint.java
@@ -16,8 +16,11 @@
  */
 package org.apache.camel.component.rest.openapi;
 
+import java.io.File;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -54,15 +57,18 @@ import org.apache.camel.ExchangePattern;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.Resource;
 import org.apache.camel.spi.RestConfiguration;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriPath;
 import org.apache.camel.support.CamelContextHelper;
 import org.apache.camel.support.DefaultEndpoint;
+import org.apache.camel.support.ResourceHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.UnsafeUriCharactersEncoder;
+import org.apache.commons.io.FileUtils;
 import org.slf4j.LoggerFactory;
 
 import static java.util.Optional.ofNullable;
@@ -714,11 +720,36 @@ public final class RestOpenApiEndpoint extends DefaultEndpoint {
         final OpenAPIParser openApiParser = new OpenAPIParser();
         final ParseOptions options = new ParseOptions();
         options.setResolveFully(true);
-        final SwaggerParseResult openApi = openApiParser.readLocation(uriAsString, null, options);
 
-        if (openApi != null && openApi.getOpenAPI() != null) {
-            checkV2specification(openApi.getOpenAPI(), uri);
-            return openApi.getOpenAPI();
+        File tmpFileToDelete = null;
+        try {
+            Resource resource = ResourceHelper.resolveMandatoryResource(camelContext, uriAsString);
+            //if location can not be used in Swagger API (e.g. in case of "bean;")
+            // the content of the resource has to be copied into a tmp file for swagger API.
+            String locationToSearch;
+            if ("bean:".equals(ResourceHelper.getScheme(uriAsString))) {
+                Path tmpFile = Files.createTempFile(null, null);
+                tmpFileToDelete = tmpFile.toFile();
+                tmpFileToDelete.deleteOnExit();
+                FileUtils.copyInputStreamToFile(resource.getInputStream(), tmpFileToDelete);
+                locationToSearch = tmpFile.toUri().toString();
+            } else {
+                locationToSearch = resource.getURI().toString();
+            }
+
+            final SwaggerParseResult openApi = openApiParser.readLocation(locationToSearch, null, options);
+
+            if (openApi != null && openApi.getOpenAPI() != null) {
+                checkV2specification(openApi.getOpenAPI(), uri);
+                return openApi.getOpenAPI();
+            }
+        } catch (Exception e) {
+            throw new IllegalArgumentException(
+                    "The given OpenApi specification could not be loaded from `" + uri + "`.", e);
+        } finally {
+            if (tmpFileToDelete != null) {
+                tmpFileToDelete.delete();
+            }
         }
 
         // In theory there should be a message in the parse result but it has disappeared...
diff --git a/components/camel-rest-openapi/src/test/java/org/apache/camel/component/rest/openapi/RestOpenApiBean.java b/components/camel-rest-openapi/src/test/java/org/apache/camel/component/rest/openapi/RestOpenApiBean.java
new file mode 100644
index 00000000000..0272484dedf
--- /dev/null
+++ b/components/camel-rest-openapi/src/test/java/org/apache/camel/component/rest/openapi/RestOpenApiBean.java
@@ -0,0 +1,29 @@
+/*
+ * 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.component.rest.openapi;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+public class RestOpenApiBean {
+    public String getOpenApiJson() throws IOException {
+        try (InputStream is = getClass().getClassLoader().getResourceAsStream("openapi.json")) {
+            return new String(is.readAllBytes(), StandardCharsets.UTF_8);
+        }
+    }
+}
diff --git a/components/camel-rest-openapi/src/test/java/org/apache/camel/component/rest/openapi/RestOpenApiComponentTest.java b/components/camel-rest-openapi/src/test/java/org/apache/camel/component/rest/openapi/RestOpenApiComponentTest.java
index 0ddc0428185..bace42d5569 100644
--- a/components/camel-rest-openapi/src/test/java/org/apache/camel/component/rest/openapi/RestOpenApiComponentTest.java
+++ b/components/camel-rest-openapi/src/test/java/org/apache/camel/component/rest/openapi/RestOpenApiComponentTest.java
@@ -41,6 +41,7 @@ import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
 import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
@@ -107,6 +108,27 @@ public class RestOpenApiComponentTest extends CamelTestSupport {
                         .withHeader("Content-Type", equalTo("application/xml")));
     }
 
+    @ParameterizedTest
+    @ValueSource(strings = { "Classpath", "Bean", "File" })
+    public void shouldBeAddingPetsDifferentLookup(String startPath) throws Exception {
+        doSetUp("http");
+
+        final Pet pet = new Pet();
+        pet.name = "Jean-Luc Picard";
+
+        final Pet created = template.requestBody("direct:addPetVia" + startPath, pet, Pet.class);
+
+        assertNotNull(created);
+
+        assertEquals(Integer.valueOf(14), created.id);
+
+        petstore.verify(
+                postRequestedFor(urlEqualTo("/v2/pet"))
+                        // Swagger V2 converted to V3 ignores "produces" if there is no associated response schema
+                        //.withHeader("Accept", equalTo("application/xml, application/json"))
+                        .withHeader("Content-Type", equalTo("application/xml")));
+    }
+
     @ParameterizedTest
     @MethodSource("knownProducers")
     public void shouldBeGettingPetsById(String componentName) throws Exception {
@@ -212,6 +234,8 @@ public class RestOpenApiComponentTest extends CamelTestSupport {
 
         camelContext.addComponent("altPetStore", altPetStore);
 
+        camelContext.getRegistry().bind("openapiBean", new RestOpenApiBean());
+
         return camelContext;
     }
 
@@ -230,7 +254,14 @@ public class RestOpenApiComponentTest extends CamelTestSupport {
 
                 from("direct:getPetByIdWithEndpointParams").to("petStore:getPetById?petId=14").unmarshal(jaxb);
 
-                from("direct:addPet").marshal(jaxb).to("petStore:addPet").unmarshal(jaxb);
+                from("direct:addPet").marshal(jaxb).to("petStore:addPet?specificationUri=classpath:openapi.json")
+                        .unmarshal(jaxb);
+                from("direct:addPetViaClasspath").marshal(jaxb).to("petStore:addPet?specificationUri=classpath:openapi.json")
+                        .unmarshal(jaxb);
+                from("direct:addPetViaBean").marshal(jaxb)
+                        .to("petStore:addPet?specificationUri=bean:openapiBean.getOpenApiJson").unmarshal(jaxb);
+                from("direct:addPetViaFile").marshal(jaxb)
+                        .to("petStore:addPet?specificationUri=file:target/test-classes/openapi.json").unmarshal(jaxb);
 
                 from("direct:findPetsByStatus").to("petStore:findPetsByStatus").unmarshal(jaxb);
             }