From f87d9d6182088aeb1dd4b6a0f792b456d02c339c Mon Sep 17 00:00:00 2001 From: James Netherton Date: Mon, 27 Jun 2022 09:17:46 +0100 Subject: [PATCH] Temporarily work around Vert.x incompatibilities between Camel & Quarkus --- extensions/platform-http/runtime/pom.xml | 5 ++ ...CamelQuarkusVertxPlatformHttpConsumer.java | 89 +++++++++++++++++++ .../graal/PlatformHttpVertxSubstitutions.java | 36 ++++++++ .../http/runtime/PlatformHttpRecorder.java | 14 ++- .../http/server/it/PlatformHttpTest.java | 4 +- 5 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 extensions/platform-http/runtime/src/main/java/org/apache/camel/component/platform/http/vertx/CamelQuarkusVertxPlatformHttpConsumer.java create mode 100644 extensions/platform-http/runtime/src/main/java/org/apache/camel/quarkus/component/platform/http/graal/PlatformHttpVertxSubstitutions.java diff --git a/extensions/platform-http/runtime/pom.xml b/extensions/platform-http/runtime/pom.xml index acb533ad4e4e..16b331476f15 100644 --- a/extensions/platform-http/runtime/pom.xml +++ b/extensions/platform-http/runtime/pom.xml @@ -52,6 +52,11 @@ io.quarkus quarkus-vertx-http + + org.graalvm.nativeimage + svm + provided + 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 000000000000..346ecf6dac8a --- /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> 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 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 000000000000..27f7642d51da --- /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 4c77bfb0f30c..970bd2e46cc3 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.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 createEngine() { - return new RuntimeValue<>(new VertxPlatformHttpEngine()); + return new RuntimeValue<>(new CamelQuarkusVertxPlatformHttpEngine()); } public RuntimeValue createComponent(RuntimeValue engine) { @@ -50,4 +54,12 @@ public Handler bodyHandler() { }; 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 84d442b1b6f5..38cae384246b 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.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 @@ public void registrySetUp() { .then() .statusCode(200) .body( - "engine", is(VertxPlatformHttpEngine.class.getName()), + "engine", endsWith("CamelQuarkusVertxPlatformHttpEngine"), "component", is(PlatformHttpComponent.class.getName())); }