You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pp...@apache.org on 2021/07/26 20:27:41 UTC
[camel-quarkus] branch main updated: Stress the more preferred way
of configuring components via CDI by moving it up
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 <pp...@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"));
+ }
+
}