You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2022/06/29 06:29:50 UTC

[camel-quarkus] 03/03: Temporarily work around Vert.x incompatibilities between Camel & Quarkus

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

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

commit 142888916e2baa2a05eaa87355aae1eaaa0dde6d
Author: James Netherton <ja...@gmail.com>
AuthorDate: Mon Jun 27 09:17:46 2022 +0100

    Temporarily work around Vert.x incompatibilities between Camel & Quarkus
---
 extensions/platform-http/runtime/pom.xml           |  5 ++
 .../CamelQuarkusVertxPlatformHttpConsumer.java     | 89 ++++++++++++++++++++++
 .../http/graal/PlatformHttpVertxSubstitutions.java | 36 +++++++++
 .../http/runtime/PlatformHttpRecorder.java         | 14 +++-
 .../component/http/server/it/PlatformHttpTest.java |  4 +-
 5 files changed, 145 insertions(+), 3 deletions(-)

diff --git a/extensions/platform-http/runtime/pom.xml b/extensions/platform-http/runtime/pom.xml
index acb533ad4e..16b331476f 100644
--- a/extensions/platform-http/runtime/pom.xml
+++ b/extensions/platform-http/runtime/pom.xml
@@ -52,6 +52,11 @@
             <groupId>io.quarkus</groupId>
             <artifactId>quarkus-vertx-http</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.graalvm.nativeimage</groupId>
+            <artifactId>svm</artifactId>
+            <scope>provided</scope>
+        </dependency>
 
     </dependencies>
 
diff --git a/extensions/platform-http/runtime/src/main/java/org/apache/camel/component/platform/http/vertx/CamelQuarkusVertxPlatformHttpConsumer.java b/extensions/platform-http/runtime/src/main/java/org/apache/camel/component/platform/http/vertx/CamelQuarkusVertxPlatformHttpConsumer.java
new file mode 100644
index 0000000000..346ecf6dac
--- /dev/null
+++ b/extensions/platform-http/runtime/src/main/java/org/apache/camel/component/platform/http/vertx/CamelQuarkusVertxPlatformHttpConsumer.java
@@ -0,0 +1,89 @@
+/*
+ * 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.platform.http.vertx;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import io.vertx.core.Handler;
+import io.vertx.core.MultiMap;
+import io.vertx.core.buffer.Buffer;
+import io.vertx.ext.web.RoutingContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.component.platform.http.PlatformHttpEndpoint;
+import org.apache.camel.component.platform.http.spi.Method;
+import org.apache.camel.spi.HeaderFilterStrategy;
+
+import static org.apache.camel.component.platform.http.vertx.VertxPlatformHttpSupport.appendHeader;
+import static org.apache.camel.component.platform.http.vertx.VertxPlatformHttpSupport.populateCamelHeaders;
+
+// TODO: Remove when Camel / Quarkus Vert.x version is in sync https://github.com/apache/camel-quarkus/issues/3877
+public final class CamelQuarkusVertxPlatformHttpConsumer extends VertxPlatformHttpConsumer {
+
+    public CamelQuarkusVertxPlatformHttpConsumer(PlatformHttpEndpoint endpoint, Processor processor,
+            List<Handler<RoutingContext>> handlers) {
+        super(endpoint, processor, handlers);
+    }
+
+    @Override
+    protected Message toCamelMessage(RoutingContext ctx, Exchange exchange) {
+        final Message result = exchange.getIn();
+
+        final HeaderFilterStrategy headerFilterStrategy = getEndpoint().getHeaderFilterStrategy();
+        populateCamelHeaders(ctx, result.getHeaders(), exchange, headerFilterStrategy);
+        final String mimeType = ctx.parsedHeaders().contentType().value();
+        final boolean isMultipartFormData = "multipart/form-data".equals(mimeType);
+        if ("application/x-www-form-urlencoded".equals(mimeType) || isMultipartFormData) {
+            final MultiMap formData = ctx.request().formAttributes();
+            final Map<String, Object> body = new HashMap<>();
+            for (String key : formData.names()) {
+                for (String value : formData.getAll(key)) {
+                    if (headerFilterStrategy != null
+                            && !headerFilterStrategy.applyFilterToExternalHeaders(key, value, exchange)) {
+                        appendHeader(result.getHeaders(), key, value);
+                        appendHeader(body, key, value);
+                    }
+                }
+            }
+
+            if (!body.isEmpty()) {
+                result.setBody(body);
+            }
+
+            if (isMultipartFormData) {
+                populateAttachments(new ArrayList<>(ctx.fileUploads()), result);
+            }
+        } else {
+            Method m = Method.valueOf(ctx.request().method().name());
+            if (m.canHaveBody()) {
+                final Buffer body = ctx.getBody();
+                if (body != null) {
+                    result.setBody(body);
+                } else {
+                    result.setBody(null);
+                }
+            } else {
+                result.setBody(null);
+            }
+        }
+        return result;
+    }
+}
diff --git a/extensions/platform-http/runtime/src/main/java/org/apache/camel/quarkus/component/platform/http/graal/PlatformHttpVertxSubstitutions.java b/extensions/platform-http/runtime/src/main/java/org/apache/camel/quarkus/component/platform/http/graal/PlatformHttpVertxSubstitutions.java
new file mode 100644
index 0000000000..27f7642d51
--- /dev/null
+++ b/extensions/platform-http/runtime/src/main/java/org/apache/camel/quarkus/component/platform/http/graal/PlatformHttpVertxSubstitutions.java
@@ -0,0 +1,36 @@
+/*
+ * 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.quarkus.component.platform.http.graal;
+
+import com.oracle.svm.core.annotate.Substitute;
+import com.oracle.svm.core.annotate.TargetClass;
+import io.vertx.ext.web.RoutingContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.platform.http.vertx.VertxPlatformHttpConsumer;
+
+@TargetClass(VertxPlatformHttpConsumer.class)
+public final class PlatformHttpVertxSubstitutions {
+
+    // Remove incompatible Vert.x API usage. This method is overridden in
+    // CamelQuarkusVertxPlatformHttpConsumer. So it's safe to effectively replace
+    // the original method content and return null
+    @Substitute
+    protected Message toCamelMessage(RoutingContext ctx, Exchange exchange) {
+        return null;
+    }
+}
diff --git a/extensions/platform-http/runtime/src/main/java/org/apache/camel/quarkus/component/platform/http/runtime/PlatformHttpRecorder.java b/extensions/platform-http/runtime/src/main/java/org/apache/camel/quarkus/component/platform/http/runtime/PlatformHttpRecorder.java
index 4c77bfb0f3..970bd2e46c 100644
--- a/extensions/platform-http/runtime/src/main/java/org/apache/camel/quarkus/component/platform/http/runtime/PlatformHttpRecorder.java
+++ b/extensions/platform-http/runtime/src/main/java/org/apache/camel/quarkus/component/platform/http/runtime/PlatformHttpRecorder.java
@@ -22,15 +22,19 @@ import io.vertx.core.Handler;
 import io.vertx.core.Vertx;
 import io.vertx.ext.web.Router;
 import io.vertx.ext.web.RoutingContext;
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
 import org.apache.camel.component.platform.http.PlatformHttpComponent;
+import org.apache.camel.component.platform.http.PlatformHttpEndpoint;
 import org.apache.camel.component.platform.http.spi.PlatformHttpEngine;
+import org.apache.camel.component.platform.http.vertx.CamelQuarkusVertxPlatformHttpConsumer;
 import org.apache.camel.component.platform.http.vertx.VertxPlatformHttpEngine;
 import org.apache.camel.component.platform.http.vertx.VertxPlatformHttpRouter;
 
 @Recorder
 public class PlatformHttpRecorder {
     public RuntimeValue<PlatformHttpEngine> createEngine() {
-        return new RuntimeValue<>(new VertxPlatformHttpEngine());
+        return new RuntimeValue<>(new CamelQuarkusVertxPlatformHttpEngine());
     }
 
     public RuntimeValue<PlatformHttpComponent> createComponent(RuntimeValue<PlatformHttpEngine> engine) {
@@ -50,4 +54,12 @@ public class PlatformHttpRecorder {
         };
         return new RuntimeValue<>(vertxPlatformHttpRouter);
     }
+
+    // TODO: Remove when Camel / Quarkus Vert.x version is in sync https://github.com/apache/camel-quarkus/issues/3877
+    static final class CamelQuarkusVertxPlatformHttpEngine extends VertxPlatformHttpEngine {
+        @Override
+        public Consumer createConsumer(PlatformHttpEndpoint endpoint, Processor processor) {
+            return new CamelQuarkusVertxPlatformHttpConsumer(endpoint, processor, getHandlers());
+        }
+    }
 }
diff --git a/integration-tests/platform-http/src/test/java/org/apache/camel/quarkus/component/http/server/it/PlatformHttpTest.java b/integration-tests/platform-http/src/test/java/org/apache/camel/quarkus/component/http/server/it/PlatformHttpTest.java
index 84d442b1b6..38cae38424 100644
--- a/integration-tests/platform-http/src/test/java/org/apache/camel/quarkus/component/http/server/it/PlatformHttpTest.java
+++ b/integration-tests/platform-http/src/test/java/org/apache/camel/quarkus/component/http/server/it/PlatformHttpTest.java
@@ -24,13 +24,13 @@ import io.restassured.RestAssured;
 import io.restassured.http.ContentType;
 import io.restassured.http.Method;
 import org.apache.camel.component.platform.http.PlatformHttpComponent;
-import org.apache.camel.component.platform.http.vertx.VertxPlatformHttpEngine;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.MethodSource;
 
+import static org.hamcrest.CoreMatchers.endsWith;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.Matchers.notNullValue;
@@ -357,7 +357,7 @@ class PlatformHttpTest {
                 .then()
                 .statusCode(200)
                 .body(
-                        "engine", is(VertxPlatformHttpEngine.class.getName()),
+                        "engine", endsWith("CamelQuarkusVertxPlatformHttpEngine"),
                         "component", is(PlatformHttpComponent.class.getName()));
     }