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 e56c480ca2a CAMEL-21140: camel-core - Add init/destroy method support
for registry bind
e56c480ca2a is described below
commit e56c480ca2a1f4541e6b3a57381b559096934c13
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Aug 29 19:39:12 2024 +0200
CAMEL-21140: camel-core - Add init/destroy method support for registry bind
---
.../main/java/org/apache/camel/BindToRegistry.java | 6 ++
.../impl/engine/DefaultCamelBeanPostProcessor.java | 14 ++++
...efaultDependencyInjectionAnnotationFactory.java | 6 +-
...ToRegistryBeanInitDestroyMethodServiceTest.java | 89 ++++++++++++++++++++++
.../org/apache/camel/support/DefaultRegistry.java | 1 +
.../camel/support/scan/PackageScanHelper.java | 16 +++-
.../injection/AnnotationDependencyInjection.java | 2 +-
7 files changed, 129 insertions(+), 5 deletions(-)
diff --git a/core/camel-api/src/main/java/org/apache/camel/BindToRegistry.java
b/core/camel-api/src/main/java/org/apache/camel/BindToRegistry.java
index 15ea5a3cf65..3c68788d609 100644
--- a/core/camel-api/src/main/java/org/apache/camel/BindToRegistry.java
+++ b/core/camel-api/src/main/java/org/apache/camel/BindToRegistry.java
@@ -55,11 +55,17 @@ public @interface BindToRegistry {
/**
* The optional name of a method to call on the bean instance during
initialization.
+ *
+ * If the bean is an {@link Service} instance then Camel will
automatically use start as init method, if none
+ * explicit configured.
*/
String initMethod() default "";
/**
* The optional name of a method to call on the bean instance during
destruction.
+ *
+ * If the bean is an {@link Service} instance then Camel will
automatically use stop as destroy method, if none
+ * explicit configured.
*/
String destroyMethod() default "";
}
diff --git
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
index 12c14e21507..6781a0163c0 100644
---
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
+++
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
@@ -35,6 +35,7 @@ import org.apache.camel.EndpointInject;
import org.apache.camel.Produce;
import org.apache.camel.PropertyInject;
import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.Service;
import org.apache.camel.spi.CamelBeanPostProcessor;
import org.apache.camel.spi.CamelBeanPostProcessorInjector;
import org.apache.camel.support.DefaultEndpoint;
@@ -539,6 +540,12 @@ public class DefaultCamelBeanPostProcessor implements
CamelBeanPostProcessor, Ca
if (unbindEnabled) {
getOrLookupCamelContext().getRegistry().unbind(name);
}
+ if (isEmpty(initMethod) && bean instanceof Service) {
+ initMethod = "start";
+ }
+ if (isEmpty(destroyMethod) && bean instanceof Service) {
+ destroyMethod = "stop";
+ }
// use dependency injection factory to perform the task of binding the
bean to registry
Runnable task =
PluginHelper.getDependencyInjectionAnnotationFactory(getOrLookupCamelContext())
.createBindToRegistryFactory(name, bean, clazz, beanName,
postProcess, initMethod, destroyMethod);
@@ -573,6 +580,13 @@ public class DefaultCamelBeanPostProcessor implements
CamelBeanPostProcessor, Ca
value = ReflectionHelper.getField(field, bean);
}
if (value != null) {
+ // automatic support Service for init/destroy methods
+ if (isEmpty(initMethod) && bean instanceof Service) {
+ initMethod = "start";
+ }
+ if (isEmpty(destroyMethod) && bean instanceof Service) {
+ destroyMethod = "stop";
+ }
if (unbindEnabled) {
getOrLookupCamelContext().getRegistry().unbind(name);
}
diff --git
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultDependencyInjectionAnnotationFactory.java
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultDependencyInjectionAnnotationFactory.java
index 6344ae89373..b665e0209fe 100644
---
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultDependencyInjectionAnnotationFactory.java
+++
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultDependencyInjectionAnnotationFactory.java
@@ -68,7 +68,11 @@ public class DefaultDependencyInjectionAnnotationFactory
Supplier<Object> sup = (Supplier<Object>) bean;
camelContext.getRegistry().bind(id, beanType, sup);
} else {
- camelContext.getRegistry().bind(id, bean, initMethod,
destroyMethod);
+ if (initMethod != null || destroyMethod != null) {
+ camelContext.getRegistry().bind(id, bean, initMethod,
destroyMethod);
+ } else {
+ camelContext.getRegistry().bind(id, bean);
+ }
}
};
}
diff --git
a/core/camel-core/src/test/java/org/apache/camel/impl/BindToRegistryBeanInitDestroyMethodServiceTest.java
b/core/camel-core/src/test/java/org/apache/camel/impl/BindToRegistryBeanInitDestroyMethodServiceTest.java
new file mode 100644
index 00000000000..aabfccc7ac5
--- /dev/null
+++
b/core/camel-core/src/test/java/org/apache/camel/impl/BindToRegistryBeanInitDestroyMethodServiceTest.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.impl;
+
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Service;
+import org.apache.camel.support.PluginHelper;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class BindToRegistryBeanInitDestroyMethodServiceTest extends
ContextTestSupport {
+
+ @BindToRegistry
+ public FooService myFoo() {
+ return new FooService("World");
+ }
+
+ @Test
+ public void testStop() throws Exception {
+ // bean post processing dont run on ContextTestSupport
+ Runnable task =
PluginHelper.getDependencyInjectionAnnotationFactory(context)
+ .createBindToRegistryFactory("myFoo", myFoo(),
FooService.class, "myFoo", false, "start", "stop");
+ task.run();
+
+ FooService foo = context.getRegistry().lookupByNameAndType("myFoo",
FooService.class);
+ assertNotNull(foo);
+ assertEquals("Started World", foo.getMessage());
+
+ // stop camel should trigger destroy
+ context.stop();
+
+ assertEquals("Stopped", foo.getMessage());
+ }
+
+ @Test
+ public void testUnbind() throws Exception {
+ // bean post processing dont run on ContextTestSupport
+ Runnable task =
PluginHelper.getDependencyInjectionAnnotationFactory(context)
+ .createBindToRegistryFactory("myFoo", myFoo(),
FooService.class, "myFoo", false, "start", "stop");
+ task.run();
+
+ FooService foo = context.getRegistry().lookupByNameAndType("myFoo",
FooService.class);
+ assertNotNull(foo);
+ assertEquals("Started World", foo.getMessage());
+
+ // unbind should trigger destroy
+ context.getRegistry().unbind("myFoo");
+ assertEquals("Stopped", foo.getMessage());
+ }
+
+ public static class FooService implements Service {
+
+ private String message;
+
+ public FooService(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void start() {
+ this.message = "Started " + message;
+ }
+
+ public void stop() {
+ this.message = "Stopped";
+ }
+
+ }
+}
diff --git
a/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java
b/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java
index 598a5900534..4b08844eb57 100644
---
a/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java
+++
b/core/camel-support/src/main/java/org/apache/camel/support/DefaultRegistry.java
@@ -42,6 +42,7 @@ import org.apache.camel.util.function.Suppliers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static org.apache.camel.util.ObjectHelper.isEmpty;
import static org.apache.camel.util.ObjectHelper.isNotEmpty;
/**
diff --git
a/core/camel-support/src/main/java/org/apache/camel/support/scan/PackageScanHelper.java
b/core/camel-support/src/main/java/org/apache/camel/support/scan/PackageScanHelper.java
index e405e4550cd..658b5bae758 100644
---
a/core/camel-support/src/main/java/org/apache/camel/support/scan/PackageScanHelper.java
+++
b/core/camel-support/src/main/java/org/apache/camel/support/scan/PackageScanHelper.java
@@ -26,6 +26,7 @@ import java.util.function.Supplier;
import org.apache.camel.BindToRegistry;
import org.apache.camel.CamelContext;
import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.Service;
import org.apache.camel.spi.CamelBeanPostProcessor;
import org.apache.camel.spi.Injector;
import org.apache.camel.spi.PackageScanClassResolver;
@@ -117,13 +118,22 @@ public class PackageScanHelper {
}
Object bean = entry.getValue();
String beanName = c.getName();
+ // special for init method as we need to defer
calling it at a late phase
+ String initMethod = ann.initMethod();
+ if (isEmpty(initMethod) && bean instanceof
Service) {
+ initMethod = "start";
+ }
+ String destroyMethod = ann.destroyMethod();
+ if (isEmpty(destroyMethod) && bean instanceof
Service) {
+ destroyMethod = "stop";
+ }
// - bind to registry if
@org.apache.camel.BindToRegistry is present
// use dependency injection factory to perform
the task of binding the bean to registry
Runnable task =
PluginHelper.getDependencyInjectionAnnotationFactory(camelContext)
- .createBindToRegistryFactory(name,
bean, c, beanName, false, null, ann.destroyMethod());
+ .createBindToRegistryFactory(name,
bean, c, beanName, false, null, destroyMethod);
// defer calling init methods until dependency
injection in phase-4 is complete
- if (isNotEmpty(ann.initMethod())) {
- initMethods.put(bean, ann.initMethod());
+ if (isNotEmpty(initMethod)) {
+ initMethods.put(bean, initMethod);
}
task.run();
}
diff --git
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/injection/AnnotationDependencyInjection.java
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/injection/AnnotationDependencyInjection.java
index fd41ea4ed3e..912d80a7222 100644
---
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/injection/AnnotationDependencyInjection.java
+++
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/injection/AnnotationDependencyInjection.java
@@ -159,7 +159,7 @@ public final class AnnotationDependencyInjection {
camelContext.getRegistry().unbind(beanName);
// use dependency injection factory to perform the task of
binding the bean to registry
Runnable task =
PluginHelper.getDependencyInjectionAnnotationFactory(camelContext)
- .createBindToRegistryFactory(name, instance, clazz,
beanName, false);
+ .createBindToRegistryFactory(name, instance, clazz,
beanName, false, bir.initMethod(), bir.destroyMethod());
task.run();
} else {
if (bir != null || cfg != null || instance instanceof
CamelConfiguration) {