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

Reply via email to