【问题标题】:transform mule message payload to snmp trap or pdu object将 mule 消息负载转换为 snmp 陷阱或 pdu 对象
【发布时间】:2013-06-27 12:59:35
【问题描述】:

我已经应用了一个使用 snmp4j 发送和接收陷阱的示例,一切正常。
但问题是:
当使用 mule esb 接收 snmp 陷阱时,我无法将 传入消息负载 转换为 PDU(或任何适合 snmp4j 的对象)以提取数据来自,我做了很多搜索,但徒劳无功。
谁能帮助我:
将我从 udp 端点收到的 mule esb 消息有效负载转换为 org.snmp4j.PDU 对象以从中提取陷阱数据?
这是我的代码:

公共同步 MuleEvent 过程(MuleEvent 事件)抛出 MuleException {
        byte[] encodedMessage = event.getMessage().getPayload(byte[].class);
        //下一行不起作用,但它是我正在寻找的唯一示例
        PDU pdu = 新 PDU(encodedMessage);
.....

非常感谢任何帮助

【问题讨论】:

  • byte[] 有效载荷包含哪些内容?它是一个序列化的org.snmp4j.PDU 对象吗?还有什么?

标签: mule snmp snmp4j


【解决方案1】:
public class SNMP4JParser implements Callable {

    /**
     * The following objects are all necessary in order to use SNMP4j as a parser for raw messages.
     * This was all inspired by SNMP4j source code, in particular MessageDispatcherImpl.java
     */
    private MessageProcessingModel model = null;
    private MessageDispatcher dispatcher = null;
    private Address listenAddress = null;
    private Integer32 messageProcessingModel = null;
    private Integer32 securityModel = null;
    private OctetString securityName = null;
    private Integer32 securityLevel = null;
    private PduHandle handle = null;
    private StatusInformation statusInfo = null;
    private MutableStateReference mutableStateReference = null;

    /**
     * Taken from org.snmp4j.transport.AbstractTransportMapping class
     */
    protected Integer32 maxInboundMessageSize = new Integer32 ( (1 << 16) - 1 );

    /**
     * Taken from org.snmp4j.MessageDispatcherImpl class
     */
    private int transactionID = new Random().nextInt(Integer.MAX_VALUE - 2) + 1;

    /**
     * Create all objects that SNMP4j needs to parse a raw SNMP message
     */
    public SNMP4JParser()
    {
        model = new MPv1();
        dispatcher = new MessageDispatcherImpl();
        listenAddress = GenericAddress.parse("udp:0.0.0.0/2001");
        messageProcessingModel = new Integer32();
        securityModel = new Integer32();
        securityName = new OctetString();
        securityLevel = new Integer32();
        handle = new PduHandle(transactionID);
        statusInfo = new StatusInformation();
        mutableStateReference = new MutableStateReference();
    }

    /**
     * @see org.mule.api.lifecycle.Callable#onCall(org.mule.api.MuleEventContext)
     */
    @Override
    public Object onCall(MuleEventContext eventContext) throws Exception
    {
        byte[] payloadBytes = eventContext.getMessage().getPayloadAsBytes();
        ByteBuffer buffer = ByteBuffer.wrap(payloadBytes);
        BERInputStream wholeMessage = new BERInputStream(buffer);
        MutablePDU mutablePdu = new MutablePDU();

        int status = model.prepareDataElements(
                dispatcher, 
                listenAddress, 
                wholeMessage,
                messageProcessingModel, 
                securityModel,
                securityName, 
                securityLevel, 
                mutablePdu,
                handle, 
                maxInboundMessageSize, 
                statusInfo,
                mutableStateReference);

        if ( status !=  SnmpConstants.SNMP_MP_OK )
            throw new RuntimeException(
                "Couldn't parse SNMP message. model.prepareDataElements() returned " + status);

        return mutablePdu.getPdu();
    }

}

我已经用这样的流程对其进行了测试(我使用了 snmp4j-1.11.5mule-standalone-3.4.0

<udp:connector name="connector" doc:name="UDP"/>
<flow name="snmp-demo-trapHandlingFlow" doc:name="snmp-demo-trapHandlingFlow">
    <udp:inbound-endpoint host="0.0.0.0" port="2001" responseTimeout="10000"  doc:name="UDP"/>
    <logger message="TRAP RECEIVED - #[System.currentTimeMillis()]" level="DEBUG" doc:name="Inbound timestamp"/>
    <component class="com.netboss.flow.demo.SNMP4JParser" doc:name="SNMP4JParser"/>
    [...]

而且它有效。

现在,我意识到还有一些悬而未决的问题:

  1. 有没有更好/更有效的方法?
  2. 这仅适用于 SNMP v1,如何修改上述代码以使其也适用于 v2 和 v3?

【讨论】:

    【解决方案2】:

    当您实现自己的 TransportMapping 并将其与 SNMP4J MessageDispatcherImpl 关联时,您可以更轻松地将 BER 流转换为 SNMP4J PDU。然后将所有必要的 MessageProcessingModels 和 SecurityProtocols 添加到消息调度程序中。

    最后,将 CommandResponder 接口的实现添加到消息调度程序中,就完成了。

    【讨论】:

      【解决方案3】:

      您需要创建一个自定义转换器来转换相关 SNMP4J 对象中的消息负载。或者,如果 SNMP4J API 足够简单,则可以使用表达式转换器来完成。

      【讨论】:

      • 感谢您的回复,请问您有在transformer 中转换为snmp4j 对象的示例吗?
      • 不,我不知道。在您的问题中显示您所做的事情,我们将帮助您解决问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-08
      • 1970-01-01
      相关资源
      最近更新 更多