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 9825f64 CAMEL-16906: Platform-http components fail when using unmarshal. Adding back some of the work from Pasquale Congiusti in platform-http-vertx as we can use that. And for json you need to turn on jackson type converter. 9825f64 is described below commit 9825f640a104cd506487109e8d351ef84dc25118 Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Mon Sep 27 16:19:19 2021 +0200 CAMEL-16906: Platform-http components fail when using unmarshal. Adding back some of the work from Pasquale Congiusti in platform-http-vertx as we can use that. And for json you need to turn on jackson type converter. --- components/camel-platform-http-vertx/pom.xml | 5 + .../http/vertx/VertxPlatformHttpSupport.java | 39 +++-- .../http/vertx/VertxPlatformHttpEngineTest.java | 4 +- ...rtxPlatformHttpEngineWithTypeConverterTest.java | 158 +++++++++++++++++++++ .../http/vertx/VertxPlatformHttpJacksonTest.java | 59 ++++++++ 5 files changed, 249 insertions(+), 16 deletions(-) diff --git a/components/camel-platform-http-vertx/pom.xml b/components/camel-platform-http-vertx/pom.xml index 531e451..17524e3 100644 --- a/components/camel-platform-http-vertx/pom.xml +++ b/components/camel-platform-http-vertx/pom.xml @@ -70,6 +70,11 @@ </dependency> <dependency> <groupId>org.apache.camel</groupId> + <artifactId>camel-jackson</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> <artifactId>camel-log</artifactId> <scope>test</scope> </dependency> diff --git a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSupport.java b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSupport.java index fab52af..80b99c2 100644 --- a/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSupport.java +++ b/components/camel-platform-http-vertx/src/main/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpSupport.java @@ -16,6 +16,7 @@ */ package org.apache.camel.component.platform.http.vertx; +import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; @@ -166,26 +167,36 @@ public final class VertxPlatformHttpSupport { } else if (body instanceof String) { response.end((String) body); } else if (body instanceof InputStream) { - final byte[] bytes = new byte[4096]; - try (InputStream in = (InputStream) body) { - int len; - while ((len = in.read(bytes)) >= 0) { - final Buffer b = Buffer.buffer(len); - b.appendBytes(bytes, 0, len); - response.write(b); - } - } - response.end(); + writeResponseAs(response, (InputStream) body); } else if (body instanceof Buffer) { response.end((Buffer) body); } else { final TypeConverter tc = camelExchange.getContext().getTypeConverter(); - final ByteBuffer bb = tc.mandatoryConvertTo(ByteBuffer.class, camelExchange, body); - final Buffer b = Buffer.buffer(bb.capacity()); + // Try to convert to ByteBuffer for performance reason + final ByteBuffer bb = tc.tryConvertTo(ByteBuffer.class, camelExchange, body); + if (bb != null) { + final Buffer b = Buffer.buffer(bb.capacity()); + b.setBytes(0, bb); + response.end(b); + } else { + // Otherwise fallback to most generic InputStream conversion + final InputStream is = tc.mandatoryConvertTo(InputStream.class, camelExchange, body); + writeResponseAs(response, is); + } + } + } - b.setBytes(0, bb); - response.end(b); + private static void writeResponseAs(HttpServerResponse response, InputStream is) throws IOException { + final byte[] bytes = new byte[4096]; + try (InputStream in = is) { + int len; + while ((len = in.read(bytes)) >= 0) { + final Buffer b = Buffer.buffer(len); + b.appendBytes(bytes, 0, len); + response.write(b); + } } + response.end(); } static void populateCamelHeaders( diff --git a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java index 877da29..e8b3b36 100644 --- a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java +++ b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineTest.java @@ -486,11 +486,11 @@ public class VertxPlatformHttpEngineTest { } } - private CamelContext createCamelContext() throws Exception { + static CamelContext createCamelContext() throws Exception { return createCamelContext(null); } - private CamelContext createCamelContext(ServerConfigurationCustomizer customizer) throws Exception { + private static CamelContext createCamelContext(ServerConfigurationCustomizer customizer) throws Exception { int port = AvailablePortFinder.getNextAvailable(); VertxPlatformHttpServerConfiguration conf = new VertxPlatformHttpServerConfiguration(); conf.setBindPort(port); diff --git a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineWithTypeConverterTest.java b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineWithTypeConverterTest.java new file mode 100644 index 0000000..f38d3bb --- /dev/null +++ b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpEngineWithTypeConverterTest.java @@ -0,0 +1,158 @@ +/* + * 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.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.Collections; +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.Exchange; +import org.apache.camel.NoTypeConversionAvailableException; +import org.apache.camel.TypeConversionException; +import org.apache.camel.TypeConverter; +import org.apache.camel.builder.RouteBuilder; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.equalTo; + +public class VertxPlatformHttpEngineWithTypeConverterTest { + + @Test + public void testByteBufferConversion() throws Exception { + final CamelContext context = VertxPlatformHttpEngineTest.createCamelContext(); + + TypeConverter tc = mockByteBufferTypeConverter(); + context.getTypeConverterRegistry().addTypeConverter(ByteBuffer.class, Map.class, tc); + + try { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + from("platform-http:/bytebuffer") + .routeId("bytebuffer") + .setBody().constant(Collections.singletonMap("bb", "my-test")); + } + }); + + context.start(); + + given() + .when() + .get("/bytebuffer") + .then() + .statusCode(200) + .body(equalTo("ByteBuffer:my-test")); + } finally { + context.stop(); + } + } + + @Test + public void testInputStreamConversion() throws Exception { + final CamelContext context = VertxPlatformHttpEngineTest.createCamelContext(); + + TypeConverter tc = mockInputStreamTypeConverter(); + context.getTypeConverterRegistry().addTypeConverter(InputStream.class, Map.class, tc); + + try { + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + from("platform-http:/inputstream") + .routeId("inputstream") + .setBody().constant(Collections.singletonMap("is", "my-test")); + } + }); + + context.start(); + + given() + .when() + .get("/inputstream") + .then() + .statusCode(200) + .body(equalTo("InputStream:my-test")); + } finally { + context.stop(); + } + } + + private TypeConverter mockByteBufferTypeConverter() { + return new MockTypeConverter() { + @Override + public <T> T tryConvertTo(Class<T> type, Exchange exchange, Object value) { + byte[] out = ("ByteBuffer:" + ((Map) value).get("bb")).getBytes(StandardCharsets.UTF_8); + return type.cast(ByteBuffer.wrap(out)); + } + }; + } + + private TypeConverter mockInputStreamTypeConverter() { + return new MockTypeConverter() { + @Override + public <T> T convertTo(Class<T> type, Exchange exchange, Object value) throws TypeConversionException { + byte[] out = ("InputStream:" + ((Map) value).get("is")).getBytes(StandardCharsets.UTF_8); + return type.cast(new ByteArrayInputStream(out)); + } + + }; + } + + abstract class MockTypeConverter implements TypeConverter { + @Override + public boolean allowNull() { + return false; + } + + @Override + public <T> T convertTo(Class<T> type, Object value) throws TypeConversionException { + return null; + } + + @Override + public <T> T convertTo(Class<T> type, Exchange exchange, Object value) throws TypeConversionException { + return null; + } + + @Override + public <T> T mandatoryConvertTo(Class<T> type, Object value) + throws TypeConversionException, NoTypeConversionAvailableException { + return null; + } + + @Override + public <T> T mandatoryConvertTo(Class<T> type, Exchange exchange, Object value) + throws TypeConversionException, NoTypeConversionAvailableException { + return null; + } + + @Override + public <T> T tryConvertTo(Class<T> type, Object value) { + return null; + } + + @Override + public <T> T tryConvertTo(Class<T> type, Exchange exchange, Object value) { + return null; + } + } +} diff --git a/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpJacksonTest.java b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpJacksonTest.java new file mode 100644 index 0000000..2213104 --- /dev/null +++ b/components/camel-platform-http-vertx/src/test/java/org/apache/camel/component/platform/http/vertx/VertxPlatformHttpJacksonTest.java @@ -0,0 +1,59 @@ +/* + * 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 org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.jackson.JacksonConstants; +import org.junit.jupiter.api.Test; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.equalTo; + +public class VertxPlatformHttpJacksonTest { + + @Test + public void testJackson() throws Exception { + final CamelContext context = VertxPlatformHttpEngineTest.createCamelContext(); + + try { + // turn on jackson type converter + context.getGlobalOptions().put(JacksonConstants.ENABLE_TYPE_CONVERTER, "true"); + + context.addRoutes(new RouteBuilder() { + @Override + public void configure() throws Exception { + from("platform-http:/hello") + .setBody().constant("{\"hello\": \"world\"}") + .unmarshal().json(); + } + }); + + context.start(); + + given() + .when() + .get("/hello") + .then() + .statusCode(200) + .body(equalTo("{\"hello\":\"world\"}")); + } finally { + context.stop(); + } + } + +}