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 2024/03/28 14:40:43 UTC

(camel) 29/38: CAMEL-20557: Rest DSL to use openapi spec directly

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

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

commit a32952c631a4aed00709409bc4eaddd8c2eb5957
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Mar 27 09:46:49 2024 +0100

    CAMEL-20557: Rest DSL to use openapi spec directly
---
 components/camel-rest-openapi/pom.xml              |  4 ++
 .../DefaultRestOpenapiProcessorStrategy.java       | 27 ++++++++++++
 .../rest/openapi/RestOpenApiEndpoint.java          | 48 ++--------------------
 .../component/rest/openapi/RestOpenApiHelper.java  | 44 ++++++++++++++++++++
 .../rest/openapi/RestOpenApiProcessor.java         | 15 ++-----
 5 files changed, 82 insertions(+), 56 deletions(-)

diff --git a/components/camel-rest-openapi/pom.xml b/components/camel-rest-openapi/pom.xml
index 47b7d883b14..26decde74ba 100644
--- a/components/camel-rest-openapi/pom.xml
+++ b/components/camel-rest-openapi/pom.xml
@@ -48,6 +48,10 @@
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-rest</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-platform-http</artifactId>
+        </dependency>
 
          <dependency>
             <groupId>io.swagger.core.v3</groupId>
diff --git a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/DefaultRestOpenapiProcessorStrategy.java b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/DefaultRestOpenapiProcessorStrategy.java
index 4d1640e569a..2f4c9eaa996 100644
--- a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/DefaultRestOpenapiProcessorStrategy.java
+++ b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/DefaultRestOpenapiProcessorStrategy.java
@@ -23,6 +23,7 @@ import java.util.stream.Collectors;
 
 import io.swagger.v3.oas.models.OpenAPI;
 import io.swagger.v3.oas.models.Operation;
+import joptsimple.internal.Strings;
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.AsyncProducer;
 import org.apache.camel.CamelContext;
@@ -32,6 +33,7 @@ import org.apache.camel.Exchange;
 import org.apache.camel.NonManagedService;
 import org.apache.camel.Route;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.component.platform.http.PlatformHttpComponent;
 import org.apache.camel.spi.PackageScanResourceResolver;
 import org.apache.camel.spi.ProducerCache;
 import org.apache.camel.spi.Resource;
@@ -58,6 +60,7 @@ public class DefaultRestOpenapiProcessorStrategy extends ServiceSupport
     private String component = "direct";
     private String missingOperation;
     private String mockIncludePattern;
+    private final List<String> uris = new ArrayList<>();
 
     @Override
     public void validateOpenApi(OpenAPI openAPI) throws Exception {
@@ -95,6 +98,24 @@ public class DefaultRestOpenapiProcessorStrategy extends ServiceSupport
                 LOG.debug(msg + ". This validation error is ignored (Will return a mocked/empty response).");
             }
         }
+
+        // enlist open-api rest services
+        PlatformHttpComponent phc = camelContext.getComponent("platform-http", PlatformHttpComponent.class);
+        if (phc != null) {
+            String path = RestOpenApiHelper.getBasePathFromOpenApi(openAPI);
+            if (path == null || path.isEmpty() || path.equals("/")) {
+                path = "";
+            }
+            for (var p : openAPI.getPaths().entrySet()) {
+                String uri = path + p.getKey();
+                String verbs = Strings.join(p.getValue().readOperationsMap().keySet().stream()
+                        .map(Enum::name)
+                        .sorted()
+                        .collect(Collectors.toList()), ",");
+                phc.addHttpEndpoint(uri, verbs, null, null, null);
+                uris.add(uri);
+            }
+        }
     }
 
     @Override
@@ -236,6 +257,12 @@ public class DefaultRestOpenapiProcessorStrategy extends ServiceSupport
     @Override
     protected void doStop() throws Exception {
         ServiceHelper.stopService(producerCache);
+
+        PlatformHttpComponent phc = camelContext.getComponent("platform-http", PlatformHttpComponent.class);
+        if (phc != null) {
+            uris.forEach(phc::removeHttpEndpoint);
+            uris.clear();
+        }
     }
 
 }
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 d01aba71ec7..0ef9aa3703e 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
@@ -30,8 +30,6 @@ import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -213,7 +211,7 @@ public final class RestOpenApiEndpoint extends DefaultEndpoint {
     public Consumer createConsumer(final Processor processor) throws Exception {
         OpenAPI doc = loadSpecificationFrom(getCamelContext(), specificationUri);
         String path = determineBasePath(doc);
-        Processor target = new RestOpenApiProcessor(this, doc, path, processor);
+        Processor target = new RestOpenApiProcessor(this, doc, path, processor, restOpenapiProcessorStrategy);
         CamelContextAware.trySetCamelContext(target, getCamelContext());
         return createConsumerFor(path, target);
     }
@@ -510,7 +508,7 @@ public final class RestOpenApiEndpoint extends DefaultEndpoint {
             return componentBasePath;
         }
 
-        final String specificationBasePath = getBasePathFromOpenApi(openapi);
+        final String specificationBasePath = RestOpenApiHelper.getBasePathFromOpenApi(openapi);
 
         if (isNotEmpty(specificationBasePath)) {
             return specificationBasePath;
@@ -528,46 +526,6 @@ public final class RestOpenApiEndpoint extends DefaultEndpoint {
         return RestOpenApiComponent.DEFAULT_BASE_PATH;
     }
 
-    public static String getBasePathFromOpenApi(final OpenAPI openApi) {
-        String basePath = null;
-        if (openApi.getServers() != null) {
-            for (Server server : openApi.getServers()) {
-                if (server.getUrl() != null) {
-                    try {
-                        URI serverUrl = new URI(parseVariables(server.getUrl(), server));
-                        basePath = serverUrl.getPath();
-                        // Is this really necessary?
-                        if (basePath.indexOf("//") == 0) {
-                            // strip off the first "/" if double "/" exists
-                            basePath = basePath.substring(1);
-                        }
-                        if ("/".equals(basePath)) {
-                            basePath = "";
-                        }
-                    } catch (URISyntaxException e) {
-                        //not a valid whole url, just the basePath
-                        basePath = server.getUrl();
-                    }
-                }
-            }
-        }
-        return basePath;
-    }
-
-    public static String parseVariables(String url, Server server) {
-        Pattern p = Pattern.compile("\\{(.*?)\\}");
-        Matcher m = p.matcher(url);
-        while (m.find()) {
-
-            String variable = m.group(1);
-            if (server != null && server.getVariables() != null && server.getVariables().get(variable) != null) {
-                String varValue = server.getVariables().get(variable).getDefault();
-                url = url.replace("{" + variable + "}", varValue);
-            }
-        }
-        return url;
-    }
-
     String determineComponentName() {
         return Optional.ofNullable(componentName).orElse(getComponent().getComponentName());
     }
@@ -753,7 +711,7 @@ public final class RestOpenApiEndpoint extends DefaultEndpoint {
         if (servers != null) {
             for (Server server : servers) {
                 try {
-                    uris.add(new URI(parseVariables(server.getUrl(), server)));
+                    uris.add(new URI(RestOpenApiHelper.parseVariables(server.getUrl(), server)));
                 } catch (URISyntaxException e) {
                     // ignore
                 }
diff --git a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiHelper.java b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiHelper.java
index 4af6a0772c8..fc8e460c551 100644
--- a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiHelper.java
+++ b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiHelper.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.rest.openapi;
 
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
@@ -23,6 +25,8 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Stream;
 
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.servers.Server;
 import org.apache.camel.spi.ContentTypeAware;
 import org.apache.camel.spi.Resource;
 import org.apache.camel.util.ObjectHelper;
@@ -90,4 +94,44 @@ final class RestOpenApiHelper {
         return location.toLowerCase().endsWith(".yml") || location.toLowerCase().endsWith(".yaml");
     }
 
+    public static String getBasePathFromOpenApi(final OpenAPI openApi) {
+        String basePath = null;
+        if (openApi.getServers() != null) {
+            for (Server server : openApi.getServers()) {
+                if (server.getUrl() != null) {
+                    try {
+                        URI serverUrl = new URI(parseVariables(server.getUrl(), server));
+                        basePath = serverUrl.getPath();
+                        // Is this really necessary?
+                        if (basePath.indexOf("//") == 0) {
+                            // strip off the first "/" if double "/" exists
+                            basePath = basePath.substring(1);
+                        }
+                        if ("/".equals(basePath)) {
+                            basePath = "";
+                        }
+                    } catch (URISyntaxException e) {
+                        //not a valid whole url, just the basePath
+                        basePath = server.getUrl();
+                    }
+                }
+            }
+        }
+        return basePath;
+    }
+
+    public static String parseVariables(String url, Server server) {
+        Pattern p = Pattern.compile("\\{(.*?)\\}");
+        Matcher m = p.matcher(url);
+        while (m.find()) {
+
+            String variable = m.group(1);
+            if (server != null && server.getVariables() != null && server.getVariables().get(variable) != null) {
+                String varValue = server.getVariables().get(variable).getDefault();
+                url = url.replace("{" + variable + "}", varValue);
+            }
+        }
+        return url;
+    }
+
 }
diff --git a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiProcessor.java b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiProcessor.java
index 35aa33035f2..429b01dcd4b 100644
--- a/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiProcessor.java
+++ b/components/camel-rest-openapi/src/main/java/org/apache/camel/component/rest/openapi/RestOpenApiProcessor.java
@@ -48,14 +48,15 @@ public class RestOpenApiProcessor extends DelegateAsyncProcessor implements Came
     private final OpenAPI openAPI;
     private final String basePath;
     private final List<RestConsumerContextPathMatcher.ConsumerPath<Operation>> paths = new ArrayList<>();
-    private RestOpenapiProcessorStrategy restOpenapiProcessorStrategy;
+    private final RestOpenapiProcessorStrategy restOpenapiProcessorStrategy;
 
-    public RestOpenApiProcessor(RestOpenApiEndpoint endpoint, OpenAPI openAPI, String basePath, Processor processor) {
+    public RestOpenApiProcessor(RestOpenApiEndpoint endpoint, OpenAPI openAPI, String basePath, Processor processor,
+                                RestOpenapiProcessorStrategy restOpenapiProcessorStrategy) {
         super(processor);
         this.endpoint = endpoint;
         this.basePath = basePath;
         this.openAPI = openAPI;
-        this.restOpenapiProcessorStrategy = new DefaultRestOpenapiProcessorStrategy();
+        this.restOpenapiProcessorStrategy = restOpenapiProcessorStrategy;
     }
 
     @Override
@@ -68,14 +69,6 @@ public class RestOpenApiProcessor extends DelegateAsyncProcessor implements Came
         this.camelContext = camelContext;
     }
 
-    public RestOpenapiProcessorStrategy getRestOpenapiProcessorStrategy() {
-        return restOpenapiProcessorStrategy;
-    }
-
-    public void setRestOpenapiProcessorStrategy(RestOpenapiProcessorStrategy restOpenapiProcessorStrategy) {
-        this.restOpenapiProcessorStrategy = restOpenapiProcessorStrategy;
-    }
-
     @Override
     public boolean process(Exchange exchange, AsyncCallback callback) {
         String path = exchange.getMessage().getHeader(Exchange.HTTP_PATH, String.class);