Thank you. This helped get me much further in this effort. The thing that I am having problems with, now, is that when I annotate the class with @ManagedResource, and then include @ManagedAttribute to methods, it will not show up as an MBean. If I remove the @ManagedResource annotation from the class, I can get it as an MBean, but I cannot see any of the things I designated as @ManagedAttribute when I get the service and get its attributes. Do you have any ideas about why this could be happening?
Thanks, Steve On Wed, Jan 3, 2024 at 5:32 AM Claus Ibsen <claus.ib...@gmail.com> wrote: > 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 <steve...@gmail.com> 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 <claus.ib...@gmail.com> 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 <steve...@gmail.com> 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 >