It needs to be added as a service.
in the producer you can do something ala
doStart
ControlService cs = new XXXX
context.addService(cs);
And remove the service in doStop
See for example SendProcessor, or do a
git grep "addService("
And look in the code for other examples
On Wed, Jan 3, 2024 at 10:57 AM Steve973 <[email protected]> wrote:
> An instance is created in the control producer. How should it be created
> in order to be managed?
>
> On Wed, Jan 3, 2024, 3:59 AM Claus Ibsen <[email protected]> wrote:
>
> > Hi
> >
> > You should not overwrite start and stop methods. But implement doStart /
> > doStop if you need any logic.
> >
> > And how do you create DynamicRouterControlService in the first place
> >
> > On Tue, Jan 2, 2024 at 11:40 PM Steve973 <[email protected]> wrote:
> >
> > > Hi, all. I was talking about this on the users list, but I found out
> > about
> > > the dev list, so I wanted to share this question with fellow camel
> > > devs/contributors.
> > >
> > > I am adding JMX reporting and control to my dynamic router eip
> component
> > > (not the original dynamic router that you can use with the DSL in
> > core). I
> > > have two services that I annotated with camel-management annotations:
> > >
> > > For JMX control (things removed for brevity):
> > >
> > > @Converter(generateBulkLoader = true)
> > > @ManagedResource(description = "Dynamic Router control operations
> > service")
> > > public class DynamicRouterControlService extends ServiceSupport {
> > >
> > > private final CamelContext camelContext;
> > >
> > > private final DynamicRouterFilterService filterService;
> > >
> > > public DynamicRouterControlService(CamelContext camelContext,
> > > DynamicRouterFilterService
> > > filterService) {
> > > this.camelContext = camelContext;
> > > this.filterService = filterService;
> > > }
> > >
> > > @ManagedOperation(description = "Subscribe for dynamic routing
> > > with a predicate expression")
> > > public String subscribeWithPredicateExpression(
> > > String subscribeChannel,
> > > String subscriptionId,
> > > String destinationUri,
> > > int priority,
> > > String predicate,
> > > String expressionLanguage,
> > > boolean update) {
> > > return filterService.addFilterForChannel(subscriptionId,
> > priority,
> > > obtainPredicateFromExpression(camelContext, predicate,
> > > expressionLanguage),
> > > destinationUri, subscribeChannel, update);
> > > }
> > >
> > > @ManagedOperation(description = "Subscribe for dynamic routing
> > > with the name of a predicate bean in the registry")
> > > public String subscribeWithPredicateBean(
> > > String subscribeChannel,
> > > String subscriptionId,
> > > String destinationUri,
> > > int priority,
> > > String predicateBean,
> > > boolean update) {
> > > return filterService.addFilterForChannel(subscriptionId,
> > priority,
> > > obtainPredicateFromBeanName(predicateBean,
> camelContext),
> > > destinationUri, subscribeChannel, update);
> > > }
> > >
> > > @ManagedOperation(description = "Subscribe for dynamic routing
> > > with a predicate instance")
> > > public String subscribeWithPredicateInstance(
> > > String subscribeChannel,
> > > String subscriptionId,
> > > String destinationUri,
> > > int priority,
> > > Object predicate,
> > > boolean update) {
> > > return filterService.addFilterForChannel(subscriptionId,
> > > priority, obtainPredicateFromInstance(predicate),
> > > destinationUri, subscribeChannel, update);
> > > }
> > >
> > > @ManagedOperation(description = "Unsubscribe for dynamic routing
> > > on a channel by subscription ID")
> > > public boolean removeSubscription(
> > > String subscribeChannel,
> > > String subscriptionId) {
> > > return filterService.removeFilterById(subscriptionId,
> > > subscribeChannel);
> > > }
> > >
> > > @Override
> > > public void start() {
> > > // no-op
> > > }
> > >
> > > @Override
> > > public void stop() {
> > > // no-op
> > > }
> > > }
> > >
> > > For reporting/monitoring (things removed for brevity):
> > >
> > > @ManagedResource(description = "Dynamic Router filter service")
> > > public class DynamicRouterFilterService extends ServiceSupport {
> > >
> > > private final Map<String,
> > > ConcurrentSkipListSet<PrioritizedFilter>> filterMap = new
> > > ConcurrentHashMap<>();
> > >
> > > private final Map<String, List<PrioritizedFilterStatistics>>
> > > filterStatisticsMap = new ConcurrentHashMap<>();
> > >
> > > private final Supplier<PrioritizedFilterFactory>
> > filterFactorySupplier;
> > >
> > > public DynamicRouterFilterService(final
> > > Supplier<PrioritizedFilterFactory> filterFactorySupplier) {
> > > this.filterFactorySupplier = filterFactorySupplier;
> > > LOG.debug("Created Dynamic Router component");
> > > }
> > >
> > > @ManagedAttribute(description = "Get the list of filters for the
> > > specified dynamic router channel")
> > > public Collection<PrioritizedFilter> getFiltersForChannel(final
> > > String channel) {
> > > return List.copyOf(filterMap.get(channel));
> > > }
> > >
> > > @ManagedAttribute(description = "Get the map of filters for all
> > > dynamic router channels")
> > > public Map<String, ConcurrentSkipListSet<PrioritizedFilter>>
> > > getFilterMap() {
> > > return Map.copyOf(filterMap);
> > > }
> > >
> > > @ManagedAttribute(description = "Get the set of filter statistics
> > > for the specified dynamic router channel")
> > > public List<PrioritizedFilterStatistics>
> > > getStatisticsForChannel(final String channel) {
> > > return List.copyOf(filterStatisticsMap.get(channel));
> > > }
> > >
> > > @ManagedAttribute(description = "Get the map of statistics for all
> > > dynamic router channels")
> > > public Map<String, List<PrioritizedFilterStatistics>>
> > > getFilterStatisticsMap() {
> > > return Map.copyOf(filterStatisticsMap);
> > > }
> > >
> > > @Override
> > > public void start() {
> > > // no-op
> > > }
> > >
> > > @Override
> > > public void stop() {
> > > // no-op
> > > }
> > > }
> > >
> > > I want to write a test that verifies that camel is registering these.
> I
> > > have added camel-management to my pom in the "test" scope. I
> originally
> > > tried to use a test annotated with @CamelSpringTest, but I could not it
> > to
> > > work, and when I tried to get the ManagementAgent, it was always null.
> > So
> > > I switched to a normal test that extends CamelTestSupport, and now I
> can
> > at
> > > least get the agent and the MBeanServer. Here is my test class:
> > >
> > > class DynamicRouterManagementIT extends CamelTestSupport {
> > >
> > > @Override
> > > protected boolean useJmx() {
> > > return true;
> > > }
> > >
> > > @Test
> > > void testExpectedMbeansExist() throws MalformedObjectNameException
> {
> > > MBeanServer mBeanServer =
> > > context.getManagementStrategy().getManagementAgent().getMBeanServer();
> > > String names = mBeanServer.queryNames(null, null).stream()
> > > .map(ObjectName::getCanonicalName)
> > > .filter(name -> name.contains("ynamic"))
> > > .collect(Collectors.joining("\n"));
> > > System.err.println("MBean names:\n" + names);
> > > }
> > >
> > > @Override
> > > protected RoutesBuilder createRouteBuilder() {
> > > return new RouteBuilder() {
> > > @Override
> > > public void configure() {
> > >
> > > from("direct:subscribe").to("dynamic-router-control:subscribe");
> > > from("direct:command").to("dynamic-router:test");
> > > }
> > > };
> > > }
> > > }
> > >
> > > The output does not show either of the two @ManagedResource classes.
> > Here
> > > is the output:
> > >
> > > MBean names:
> > > >
> > > >
> > >
> >
> org.apache.camel:context=camel-1,name="dynamic-router-control",type=components
> > > >
> org.apache.camel:context=camel-1,name="dynamic-router",type=components
> > > >
> > > >
> > >
> >
> org.apache.camel:context=camel-1,name="dynamic-router-control://subscribe",type=endpoints
> > > >
> > > >
> > >
> >
> org.apache.camel:context=camel-1,name=DynamicRouterProducer(0x511505e7),type=producers
> > > >
> > > >
> > >
> >
> org.apache.camel:context=camel-1,name=DynamicRouterControlProducer(0x70abf9b0),type=producers
> > > >
> > > >
> > >
> >
> org.apache.camel:context=camel-1,name="dynamic-router://test",type=endpoints
> > >
> > >
> > > Why don't I see the MBeans that I expect for the classes that I
> included
> > > above?
> > >
> > > Thanks,
> > > Steve
> > >
> >
> >
> > --
> > Claus Ibsen
> > -----------------
> > @davsclaus
> > Camel in Action 2: https://www.manning.com/ibsen2
> >
>
--
Claus Ibsen
-----------------
@davsclaus
Camel in Action 2: https://www.manning.com/ibsen2