This is an automated email from the ASF dual-hosted git repository. ppalaga pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push: new 7a0df68 Stress the more preferred way of configuring components via CDI by moving it up 7a0df68 is described below commit 7a0df68646419f7927eaf4ddec141a6bcfeb652e Author: Peter Palaga <ppal...@redhat.com> AuthorDate: Mon Jul 26 18:24:03 2021 +0200 Stress the more preferred way of configuring components via CDI by moving it up --- .../ROOT/pages/user-guide/configuration.adoc | 69 ++++++++++++++-------- .../camel/quarkus/component/mock/it/CdiConfig.java | 52 ++++++++++++++++ .../quarkus/component/mock/it/MockResource.java | 9 +++ .../component/mock/it/MockRouteBuilder.java | 12 ++++ .../camel/quarkus/component/mock/it/MockTest.java | 12 ++++ 5 files changed, 129 insertions(+), 25 deletions(-) diff --git a/docs/modules/ROOT/pages/user-guide/configuration.adoc b/docs/modules/ROOT/pages/user-guide/configuration.adoc index f42be4c..0bded8c 100644 --- a/docs/modules/ROOT/pages/user-guide/configuration.adoc +++ b/docs/modules/ROOT/pages/user-guide/configuration.adoc @@ -40,7 +40,49 @@ camel.component.log.exchange-formatter.show-body-type = false === CDI -The same can be done programmatically using CDI: +The same can be done programmatically using CDI. + +The best way is to observe the `ComponentAddEvent` and configure the component before the routes and the `CamelContext` are started: + +[source,java] +---- +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Observes; +import org.apache.camel.quarkus.core.events.ComponentAddEvent; +import org.apache.camel.component.log.LogComponent; +import org.apache.camel.support.processor.DefaultExchangeFormatter; + +@ApplicationScoped +public static class EventHandler { + public void onComponentAdd(@Observes ComponentAddEvent event) { + if (event.getComponent() instanceof LogComponent) { + /* Perform some custom configuration of the component */ + LogComponent logComponent = ((LogComponent) event.getComponent()); + DefaultExchangeFormatter formatter = new DefaultExchangeFormatter(); + formatter.setShowExchangePattern(false); + formatter.setShowBodyType(false); + logComponent.setExchangeFormatter(formatter); + } + } +} +---- + +==== Producing a `@Named` component instance + +Alternatively, you could create and configure the component yourself in a `@Named` producer method. +This would work thanks to the fact that Camel uses the component URI scheme to look-up components from its registry. +E.g. for `LogComponent` it would look for a `log` named bean. + +[WARNING] +==== +Please note that while producing a `@Named` component bean will work in most cases, it may cause subtle issues with some components. +Camel Quarkus extensions may do one or more of the following: ++ +* Pass custom subtype of the default Camel component type - see e.g. in https://github.com/apache/camel-quarkus/blob/main/extensions/vertx-websocket/runtime/src/main/java/org/apache/camel/quarkus/component/vertx/websocket/VertxWebsocketRecorder.java#L42[Vert.x WebSocket extension] +* Perform some Quarkus specific customization of the component - see e.g. in https://github.com/apache/camel-quarkus/blob/main/extensions/jpa/runtime/src/main/java/org/apache/camel/quarkus/component/jpa/CamelJpaRecorder.java#L35[JPA extension]. ++ +All of these get lost when you produce your own component instance. Therefore configuring components in an observer method should be preferred. +==== [source,java] ---- @@ -68,30 +110,7 @@ public class Configurations { } } ---- -<1> Camel uses the component URI scheme to look-up components from its registry, this requires you to add the `@Named` annotation to the method, otherwise the CDI container would create an anonymous bean and Camel would not be able to look it up. -The `"log"` argument of the `@Named` annotation can be omitted as long as the name of the method is the same. - -In Camel Quarkus, the Camel components are discovered during the augmentation phase. -Hence producing a new component as shown in the example above would invalidate any optimization that may have been made. - -As a better alternative you can use `@Inject` to obtain an instance of a component automatically created by Camel or you can observe one of the https://github.com/apache/camel-quarkus/tree/main/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/events[events] fired by Camel Quarkus as shown in the following example, in which we use `@Observes` to be notified about components added to the Camel Context: - -[source,java] ----- -import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.event.Observes; -import org.apache.camel.quarkus.core.events.ComponentAddEvent; -import org.apache.camel.component.log.LogComponent; - -@ApplicationScoped -public static class EventHandler { - public void onComponentAdd(@Observes ComponentAddEvent event) { - if (event.getComponent() instanceof LogComponent) { - // do something with the log component - } - } -} ----- +<1> The `"log"` argument of the `@Named` annotation can be omitted as long as the name of the method is the same. == Configuration by convention diff --git a/integration-test-groups/foundation/mock/src/main/java/org/apache/camel/quarkus/component/mock/it/CdiConfig.java b/integration-test-groups/foundation/mock/src/main/java/org/apache/camel/quarkus/component/mock/it/CdiConfig.java new file mode 100644 index 0000000..9097371 --- /dev/null +++ b/integration-test-groups/foundation/mock/src/main/java/org/apache/camel/quarkus/component/mock/it/CdiConfig.java @@ -0,0 +1,52 @@ +/* + * 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.mock.it; + +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.event.Observes; + +import org.apache.camel.component.mock.MockComponent; +import org.apache.camel.quarkus.core.events.ComponentAddEvent; +import org.apache.camel.spi.CamelEvent.CamelContextStartedEvent; +import org.jboss.logging.Logger; + +@ApplicationScoped +public class CdiConfig { + private static final Logger LOG = Logger.getLogger(CdiConfig.class); + + private final AtomicBoolean contextStarted = new AtomicBoolean(false); + + public void configureMock(@Observes ComponentAddEvent event) { + if (event.getComponent() instanceof MockComponent) { + LOG.info("Customizing the MockComponent"); + MockComponent mockComponent = (MockComponent) event.getComponent(); + assert !mockComponent.isLog(); + /* Perform some custom configuration of the component */ + mockComponent.setLog(true); + /* Make sure that what we say in docs/modules/ROOT/pages/user-guide/configuration.adoc is true */ + assert !contextStarted.get(); + } + } + + public void contextStarted(@Observes CamelContextStartedEvent event) { + LOG.info("Camel context started"); + contextStarted.set(true); + } + +} diff --git a/integration-test-groups/foundation/mock/src/main/java/org/apache/camel/quarkus/component/mock/it/MockResource.java b/integration-test-groups/foundation/mock/src/main/java/org/apache/camel/quarkus/component/mock/it/MockResource.java index 351c175..11e3101 100644 --- a/integration-test-groups/foundation/mock/src/main/java/org/apache/camel/quarkus/component/mock/it/MockResource.java +++ b/integration-test-groups/foundation/mock/src/main/java/org/apache/camel/quarkus/component/mock/it/MockResource.java @@ -22,6 +22,7 @@ import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.core.MediaType; import org.apache.camel.CamelContext; @@ -100,4 +101,12 @@ public class MockResource { mockEndpoint.assertIsSatisfied(); } + + @Path("/route/{route}") + @POST + @Consumes(MediaType.TEXT_PLAIN) + public String post(String message, @PathParam("route") String route) throws Exception { + return producerTemplate.requestBody("direct:" + route, message, String.class); + } + } diff --git a/integration-test-groups/foundation/mock/src/main/java/org/apache/camel/quarkus/component/mock/it/MockRouteBuilder.java b/integration-test-groups/foundation/mock/src/main/java/org/apache/camel/quarkus/component/mock/it/MockRouteBuilder.java index 66685ce..de30ff2 100644 --- a/integration-test-groups/foundation/mock/src/main/java/org/apache/camel/quarkus/component/mock/it/MockRouteBuilder.java +++ b/integration-test-groups/foundation/mock/src/main/java/org/apache/camel/quarkus/component/mock/it/MockRouteBuilder.java @@ -16,12 +16,20 @@ */ package org.apache.camel.quarkus.component.mock.it; +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockComponent; import org.jboss.logging.Logger; +@ApplicationScoped public class MockRouteBuilder extends RouteBuilder { private static final Logger LOG = Logger.getLogger(MockRouteBuilder.class); + @Inject + MockComponent mock; + @Override public void configure() { from("direct:mockStart") @@ -33,5 +41,9 @@ public class MockRouteBuilder extends RouteBuilder { from("direct:mockFoo") .process(e -> LOG.info("mockFoo:" + e.getMessage().getBody(String.class))) .transform(constant("Bye World")); + + from("direct:cdiConfig") + .setBody(e -> "mockComponent.log = " + mock.isLog()); + } } diff --git a/integration-test-groups/foundation/mock/src/test/java/org/apache/camel/quarkus/component/mock/it/MockTest.java b/integration-test-groups/foundation/mock/src/test/java/org/apache/camel/quarkus/component/mock/it/MockTest.java index 089ed44..9f97ead 100644 --- a/integration-test-groups/foundation/mock/src/test/java/org/apache/camel/quarkus/component/mock/it/MockTest.java +++ b/integration-test-groups/foundation/mock/src/test/java/org/apache/camel/quarkus/component/mock/it/MockTest.java @@ -19,6 +19,7 @@ package org.apache.camel.quarkus.component.mock.it; import io.quarkus.test.junit.QuarkusTest; import io.restassured.RestAssured; import io.restassured.http.ContentType; +import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; @QuarkusTest @@ -42,4 +43,15 @@ class MockTest { .statusCode(204); } + @Test + public void cdiConfig() { + RestAssured.given() + .contentType(ContentType.TEXT) + .body("foo") + .post("/mock/route/cdiConfig") + .then() + .statusCode(200) + .body(Matchers.is("mockComponent.log = true")); + } + }