Exposing class attributes to JMX for Mule custom router: what are my options?

假如想象 提交于 2019-12-10 23:24:40

问题


Using Mule Enterprise Standalone 3.1.2 I'm instrumenting attributes of the org.mule.routing.UntilSuccessful via a subclass. My subclass is used as a custom router.

<flow name="Queue Handler" processingStrategy="synchronous">
    <inbound-endpoint ref="Some.Queue">
        <vm:transaction action="ALWAYS_BEGIN"/>
    </inbound-endpoint>

    <custom-router class="com.company.product.mule.UntilSuccessfulSubclass">
        <flow-ref name="SomeFlow" />

        <spring:property name="objectStore" ref="SomeObjectStore" />
        <spring:property name="maxRetries" value="${maxRetries}" />
        <spring:property name="secondsBetweenRetries" value="${secondsBetweenRetries}" />
        <spring:property name="deadLetterQueue" ref="Cancel.Queue" />
        <spring:property name="maxThreads" value="${maxThreads}" />
        <spring:property name="maxBufferSize" value="${maxBufferSize}" />
        <spring:property name="threadTTL" value="${threadTTL}" />
    </custom-router>
</flow>

Currently I'm instrumenting the exposure via @ManagedAttribute on the getters and setters of my subclass of UntilSuccessful.

Looking at the Mule core xsd it doesn't appear that I have the option to pass in a bean instead of a class.

I'd prefer to use Spring's MBeanExporter functionality because this would allow me to avoid changing my class file by adding annotations and, more annoyingly, by having to override superclass methods just so I can instrument the JMX exposure.


回答1:


No word from MuleSoft as to when/whether the enhancement request will go through. However, MuleSoft's support team did provide a workaround:

  • Create interface that defines methods you want to expose in JMX
  • Implement interface in UntilSuccessfulSubclass
  • Include the following method in initialise():

    private void registerMBean()
    {
        final JmxSupportFactory jmxSupportFactory = AutoDiscoveryJmxSupportFactory.getInstance();
        final JmxSupport jmxSupport = jmxSupportFactory.getJmxSupport();
        final MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
    
        final String rawName = getName() + "(" + getType() + ")";
        final String name = jmxSupport.escape(rawName);
        final String jmxName = String.format("%s:%s%s", jmxSupport.getDomainName(muleContext, !muleContext.getConfiguration().isContainerMode()), "type=ODM,name=", name);
        try
        {
            final ObjectName on = jmxSupport.getObjectName(jmxName);
            final ClassloaderSwitchingMBeanWrapper mBean = new ClassloaderSwitchingMBeanWrapper(this, UntilSuccessfulMBean.class, muleContext.getExecutionClassLoader());
            logger.debug("Registering custom router with name: " + on);
            mBeanServer.registerMBean(mBean, on);
        }
        catch (final Exception e)
        {
            logger.error(e.getMessage());
        }
    }
    

This approach does not require any change to the original Mule config file (partially referenced in my original post).

One downside to this approach is that my MBean has to appear in the Mule. directory in JMX instead of grouped with all of my other MBeans outside of that context, but it gets the job done. I don't have the points to spend on digging into Mule's JMX packages but it may be possible.




回答2:


Currently Mule prevents using Spring beans directly as custom message processors, routers, ... which IMO is an oversight: since you're an EE user, you may want to open a ticket requesting an improvement for this.

Here is what you currently have to do to configure an UntilSuccessful message processor with Spring. I'm sure you can apply this to your own sub-class.

<spring:beans>
    <spring:bean id="untilSuccessful" class="org.mule.routing.UntilSuccessful">
        <spring:property name="routes">
            <util:list>
                <spring:ref bean="flowToProcess" />
            </util:list>
        </spring:property>
        <spring:property name="objectStore" ref="someObjectStore" />
        <spring:property name="maxRetries" value="5" />
        <spring:property name="secondsBetweenRetries" value="30" />
    </spring:bean>
</spring:beans>

<flow name="test">
    <vm:inbound-endpoint path="test.in"
        exchange-pattern="one-way" />

    <custom-processor class="com.myComp.MessageProcessorDelegate">
        <spring:property name="delegate" ref="untilSuccessful" />
    </custom-processor>
</flow>


package com.myComp;

import org.mule.api.MuleEvent;
import org.mule.api.MuleException;
import org.mule.api.processor.MessageProcessor;
import org.mule.processor.AbstractInterceptingMessageProcessor;

public class MessageProcessorDelegate extends AbstractInterceptingMessageProcessor
{
    private MessageProcessor delegate;

    public MuleEvent process(final MuleEvent event) throws MuleException
    {
        return delegate.process(event);
    }

    public void setDelegate(final MessageProcessor delegate)
    {
        this.delegate = delegate;
    }
}


来源:https://stackoverflow.com/questions/16967460/exposing-class-attributes-to-jmx-for-mule-custom-router-what-are-my-options

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!