You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by jb...@apache.org on 2009/08/10 15:01:48 UTC

svn commit: r802775 - in /servicemix/components/bindings/servicemix-snmp/trunk/src: main/java/org/apache/servicemix/snmp/ main/java/org/apache/servicemix/snmp/marshaler/ test/java/org/apache/servicemix/snmp/ test/resources/

Author: jbonofre
Date: Mon Aug 10 13:01:48 2009
New Revision: 802775

URL: http://svn.apache.org/viewvc?rev=802775&view=rev
Log:
[SMXCOMP-612] Add the trap-consumer endpoint.

Added:
    servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/SnmpTrapConsumerEndpoint.java   (with props)
    servicemix/components/bindings/servicemix-snmp/trunk/src/test/java/org/apache/servicemix/snmp/SnmpTrapConsumerEndpointTest.java   (with props)
    servicemix/components/bindings/servicemix-snmp/trunk/src/test/resources/spring-trap-consumer.xml   (with props)
Modified:
    servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/SnmpComponent.java
    servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/marshaler/SnmpMarshalerSupport.java

Modified: servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/SnmpComponent.java
URL: http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/SnmpComponent.java?rev=802775&r1=802774&r2=802775&view=diff
==============================================================================
--- servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/SnmpComponent.java (original)
+++ servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/SnmpComponent.java Mon Aug 10 13:01:48 2009
@@ -57,6 +57,6 @@
      * @see org.apache.servicemix.common.DefaultComponent#getEndpointClasses()
      */
     protected Class[] getEndpointClasses() {
-        return new Class[] {SnmpPollingEndpoint.class};
+        return new Class[] {SnmpPollingEndpoint.class, SnmpTrapConsumerEndpoint.class};
     }
 }

Added: servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/SnmpTrapConsumerEndpoint.java
URL: http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/SnmpTrapConsumerEndpoint.java?rev=802775&view=auto
==============================================================================
--- servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/SnmpTrapConsumerEndpoint.java (added)
+++ servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/SnmpTrapConsumerEndpoint.java Mon Aug 10 13:01:48 2009
@@ -0,0 +1,266 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.snmp;
+
+import javax.jbi.management.DeploymentException;
+import javax.jbi.messaging.InOnly;
+import javax.jbi.messaging.MessageExchange;
+import javax.jbi.messaging.MessagingException;
+import javax.jbi.messaging.NormalizedMessage;
+
+import org.apache.servicemix.common.endpoints.ConsumerEndpoint;
+import org.apache.servicemix.snmp.marshaler.DefaultSnmpMarshaler;
+import org.apache.servicemix.snmp.marshaler.SnmpMarshalerSupport;
+import org.snmp4j.CommandResponder;
+import org.snmp4j.CommandResponderEvent;
+import org.snmp4j.PDU;
+import org.snmp4j.Snmp;
+import org.snmp4j.TransportMapping;
+import org.snmp4j.smi.Address;
+import org.snmp4j.smi.GenericAddress;
+import org.snmp4j.smi.UdpAddress;
+import org.snmp4j.transport.DefaultUdpTransportMapping;
+
+/**
+ * This is the trap endpoint for the snmp component.
+ * 
+ * This endpoint receives and process trap PDUs from
+ * a device. Then it sends an exchange to the target service 
+ * containing the processed content.
+ * 
+ * @org.apache.xbean.XBean element="trap-consumer"
+ * @author gperdiguero
+ * @author jbonofre
+ */
+public class SnmpTrapConsumerEndpoint extends ConsumerEndpoint implements SnmpEndpointType, CommandResponder {
+    
+    public static final boolean DEFAULT_ENABLED_VALUE = true;
+    
+    private Address listenGenericAddress;
+    private Snmp snmp;
+    private TransportMapping transport;
+
+    private String listenAddress;
+    private boolean enabled = DEFAULT_ENABLED_VALUE;
+    
+    private SnmpMarshalerSupport marshaler = new DefaultSnmpMarshaler();
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.servicemix.common.endpoints.ConsumerEndpoint#activate()
+     */
+    @Override
+    public synchronized void activate() throws Exception {
+        super.activate();
+        // load connection data only if the endpoint is enabled
+        if (isEnabled()) {
+            logger.debug("Activating endpoint");
+            this.listenGenericAddress = GenericAddress.parse(this.listenAddress);
+            this.transport = new DefaultUdpTransportMapping((UdpAddress) this.listenGenericAddress);
+            this.snmp = new Snmp(transport);
+            snmp.addCommandResponder(this);
+        }
+    }
+    
+    /*
+     * (non-Javadoc)
+     * @see org.apache.servicemix.common.endpoints.PollingEndpoint#start()
+     */
+    @Override
+    public synchronized void start() throws Exception {
+        super.start();
+        
+        // listening is only allowed if the endpoint was initialized
+        if (isEnabled()) {
+            // listen to the transport
+            this.transport.listen();
+        }
+    }
+    
+    /*
+     * (non-Javadoc)
+     * @see org.apache.servicemix.common.endpoints.PollingEndpoint#stop()
+     */
+    @Override
+    public synchronized void stop() throws Exception {
+        // stop listening only if the endpoint was initialized
+        if (isEnabled()) {
+            // stop listening to the transport
+            if (this.transport.isListening()) {
+                this.transport.close();
+            }
+        }
+            
+        super.stop();
+    }
+    
+    /*
+     * (non-Javadoc)
+     * @see org.apache.servicemix.common.endpoints.ConsumerEndpoint#validate()
+     */
+    @Override
+    public void validate() throws DeploymentException {
+        super.validate();
+        
+        // check listen address not null
+        if (this.listenAddress == null) {
+            throw new DeploymentException("The listen address attribute has to be specified!");
+        }
+        
+        // check if address is valid
+        try {
+            if (GenericAddress.parse(this.listenAddress) == null) {
+                throw new DeploymentException("The specified address " + listenAddress + " is not valid!");
+            }
+        } catch (IllegalArgumentException ex) {
+            throw new DeploymentException("The specified address " + listenAddress + " is not valid!");
+        }
+    }
+    
+    /*
+     * (non-Javadoc)
+     * @see
+     * org.apache.servicemix.common.endpoints.AbstractEndpoint#process(javax
+     * .jbi.messaging.MessageExchange)
+     */
+    @Override
+    public void process(MessageExchange exchange) throws Exception {
+        // only DONE and ERROR states will be received here and this
+        // endpoint is not interested in such messages at all
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see
+     * org.snmp4j.CommandResponder#processPdu(org.snmp4j.CommandResponderEvent) 
+     */
+    public void processPdu(CommandResponderEvent event) {
+        PDU pdu = event.getPDU();
+        // check PDU not null
+        if (pdu != null) {
+            sendSnmpTrapMessage(pdu);
+        } else {
+            logger.debug("Received invalid trap PDU: " + pdu);
+        }
+    }
+
+    /**
+     * Sends the message to the bus 
+     * @param pdu the trap received
+     */
+    private void sendSnmpTrapMessage(PDU pdu) {
+        try {
+            // create an inOnly exchange
+            InOnly io = getExchangeFactory().createInOnlyExchange();
+            
+            // configure the exchange target
+            configureExchangeTarget(io);
+            
+            // create the in message
+            NormalizedMessage inMsg = io.createMessage();
+            
+            // now let the marshaler convert the snmp data into 
+            // a normalized message to send to jbi bus
+            this.marshaler.convertToJBI(io, inMsg, null, pdu);
+            
+            // put the in message into the inOnly exchange
+            io.setInMessage(inMsg);
+            
+            // send the exchange
+            getChannel().send(io);
+        } catch (MessagingException ex) {
+            logger.error("Error while trying to send the snmp trap PDU to the jbi bus", ex);
+        }
+    }
+
+    public Snmp getSnmp() {
+        return this.snmp;
+    }
+
+    public String getListenAddress() {
+        return this.listenAddress;
+    }
+
+    /**
+     * <p>Specifies the connection URI used to connect to a snmp capable device.
+     * <br /><br />
+     * <b><u>Template:</u></b> <br />
+     *     &nbsp;&nbsp;&nbsp;<i>&lt;protocol&gt;:&lt;host&gt;/&lt;port&gt;</i>
+     * <br /><br />
+     * <b><u>Details:</u></b><br /><br/>
+     * <table border="0" cellpadding="0" cellspacing="0">
+     * <tr>
+     *      <td width="40%" align="left"><b><u>Name</u></b></td>
+     *      <td width="60%" align="left"><b><u>Description</u></b></td>
+     * </tr>
+     * <tr>
+     *      <td>protocol</td>
+     *      <td>the protocol to use (udp or tcp)</td>
+     * </tr>
+     * <tr>
+     *      <td>host</td>
+     *      <td>the name or ip address of the snmp capable device</td>
+     * </tr>
+     * <tr>
+     *      <td>port</td>
+     *      <td>the port number to use</td>
+     * </tr>
+     * </table>
+     * <br/>
+     * <b><u>Example:</u></b><br />
+     * &nbsp;&nbsp;&nbsp;<i>udp:192.168.2.122/162</i></p>
+     * <i>&nbsp;&nbsp;&nbsp;The default value is <b>null</b></i><br/><br/>
+     * 
+     * @param listenAddress 
+     *              a <code>String</code> value containing the connection details
+     */
+    public void setListenAddress(String listenAddress) {
+        this.listenAddress = listenAddress;
+    }
+
+    public SnmpMarshalerSupport getMarshaler() {
+        return this.marshaler;
+    }
+
+    /**
+     * <p>Specifies a marshaler class which provides the logic for converting 
+     * a snmp trap into a normalized message. This class has to implement 
+     * the <code>SnmpMarshalerSupport</code> interface. If you don't specify a 
+     * marshaler, the <code>DefaultSnmpMarshaler</code> will be used.</p>
+     * 
+     * @param marshaler 
+     *              a class which implements <code>SnmpMarshalerSupport</code>
+     */
+    public void setMarshaler(SnmpMarshalerSupport marshaler) {
+        this.marshaler = marshaler;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    /**
+     * <p>Specifies wether the endpoint is enabled or not.
+     * If its value is set to true, the connection data will be
+     * setted and trap PDUs will be processed. Otherwise, 
+     * the endpoint won't do anything.</p> 
+     * @param enabled the enabled to set
+     */
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+}

Propchange: servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/SnmpTrapConsumerEndpoint.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/marshaler/SnmpMarshalerSupport.java
URL: http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/marshaler/SnmpMarshalerSupport.java?rev=802775&r1=802774&r2=802775&view=diff
==============================================================================
--- servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/marshaler/SnmpMarshalerSupport.java (original)
+++ servicemix/components/bindings/servicemix-snmp/trunk/src/main/java/org/apache/servicemix/snmp/marshaler/SnmpMarshalerSupport.java Mon Aug 10 13:01:48 2009
@@ -34,7 +34,7 @@
      * 
      * @param exchange                  the exchange object
      * @param inMsg                     the normalized message to fill
-     * @param request                   the snmp request
+     * @param request                   the snmp request. Null when PDU is a trap PDU.
      * @param response                  the snmp response
      * @throws MessagingException       on errors
      */

Added: servicemix/components/bindings/servicemix-snmp/trunk/src/test/java/org/apache/servicemix/snmp/SnmpTrapConsumerEndpointTest.java
URL: http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-snmp/trunk/src/test/java/org/apache/servicemix/snmp/SnmpTrapConsumerEndpointTest.java?rev=802775&view=auto
==============================================================================
--- servicemix/components/bindings/servicemix-snmp/trunk/src/test/java/org/apache/servicemix/snmp/SnmpTrapConsumerEndpointTest.java (added)
+++ servicemix/components/bindings/servicemix-snmp/trunk/src/test/java/org/apache/servicemix/snmp/SnmpTrapConsumerEndpointTest.java Mon Aug 10 13:01:48 2009
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.snmp;
+
+import java.io.IOException;
+
+import javax.jbi.messaging.NormalizedMessage;
+
+import org.apache.servicemix.jbi.jaxp.SourceTransformer;
+import org.apache.servicemix.tck.Receiver;
+import org.apache.servicemix.tck.SpringTestSupport;
+import org.apache.xbean.spring.context.ClassPathXmlApplicationContext;
+import org.snmp4j.CommunityTarget;
+import org.snmp4j.PDU;
+import org.snmp4j.PDUv1;
+import org.snmp4j.Snmp;
+import org.snmp4j.TransportMapping;
+import org.snmp4j.smi.Address;
+import org.snmp4j.smi.GenericAddress;
+import org.snmp4j.smi.Integer32;
+import org.snmp4j.smi.OID;
+import org.snmp4j.smi.OctetString;
+import org.snmp4j.smi.VariableBinding;
+import org.snmp4j.transport.DefaultUdpTransportMapping;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+
+/**
+ * @author gperdiguero
+ */
+public class SnmpTrapConsumerEndpointTest extends SpringTestSupport {
+    
+    private static final long TIMEOUT = 15000;
+    private static final String VAR_BIND_UDP_LOCAL = "1.3.6.1.2.1.7.5.1";
+    private static final String VAR_BIND_UDP_LOCAL_ADDRESS = ".1";
+    private static final String VAR_BIND_UDP_LOCAL_PORT = ".2";
+    private static final String listenAddress = "udp:127.0.0.1/1662";
+    
+    /**
+     * Sets up a {@link SnmpTrapConsumerEndpoint}, sends a v1 trap
+     * and waits until the receiver gets the pdu.
+     * @throws Exception
+     */
+    public void testSendAndReceiveTrap() throws Exception {
+        
+        // send a v1 trap and an inform trap
+        sendV1Trap();
+        long waitTime = System.currentTimeMillis();
+        
+        Receiver receiver = (Receiver) getBean("receiver");
+       
+        while (!receiver.getMessageList().hasReceivedMessage()) {
+            try {
+                // wait for traps
+                Thread.sleep(1000);
+            } catch (InterruptedException ex) {
+                // ignore
+            }
+            
+            if (System.currentTimeMillis() - waitTime > TIMEOUT) {
+                // don't block the build too long
+                break;
+            }
+        }
+        
+        if (receiver.getMessageList().getMessageCount() > 0) {
+            for (int i = 0 ; i < receiver.getMessageList().getMessageCount() ; i++) {
+                NormalizedMessage msg = (NormalizedMessage) receiver.getMessageList().getMessages().get(i);
+                // check if valid
+                SourceTransformer st = new SourceTransformer();
+                try {
+                    st.toDOMDocument(msg);
+                } catch (Exception e) {
+                    fail("Unable to parse the snmp trap result.\n" + st.contentToString(msg));
+                }
+            }
+        } else {
+            fail("There wasn't a PDU for " + TIMEOUT + " millis...");
+        }
+    }
+    
+    /**
+     * Sends a v1Trap PDU to the address specified in 
+     * the {@link SnmpTrapConsumerEndpoint}.
+     */
+    private void sendV1Trap() {
+        // Setting up snmp and listening address
+        Snmp snmp = null;
+        Address listenGenericAddress = GenericAddress.parse(listenAddress);
+        try {
+            TransportMapping transport = new DefaultUdpTransportMapping();
+            snmp = new Snmp(transport);
+            transport.listen();
+        } catch (IOException ioe) {
+            // ignore
+        }
+        
+        // setting up target
+        CommunityTarget target = new CommunityTarget();
+        target.setCommunity(new OctetString("private"));
+        target.setAddress(listenGenericAddress);
+        target.setRetries(2);
+        target.setTimeout(1500);
+        target.setVersion(0);
+        
+        // creating PDU. Since we are sending a V1TRAP, we have to use 
+        // a PDUv1 protocol data unit. Otherwise the trap won't be sent.
+        PDUv1 pdu = new PDUv1();
+        pdu.setType(PDU.V1TRAP);
+        pdu.setRequestID(new Integer32());
+        pdu.setTimestamp(0);
+        
+        // add a few variable bindings
+        String var_binding_name = VAR_BIND_UDP_LOCAL + VAR_BIND_UDP_LOCAL_ADDRESS + ".0.0.0.0.67";
+        pdu.add(new VariableBinding(new OID(var_binding_name), new OctetString("0.0.0.0")));
+        var_binding_name = VAR_BIND_UDP_LOCAL + VAR_BIND_UDP_LOCAL_PORT + ".0.0.0.0.67";
+        pdu.add(new VariableBinding(new OID(var_binding_name), new OctetString("67")));
+        
+        try {
+            snmp.send(pdu, target);
+        } catch (IOException ioe) {
+            // ignore
+        }
+    }
+
+    @Override
+    protected AbstractXmlApplicationContext createBeanFactory() {
+        return new ClassPathXmlApplicationContext("spring-trap-consumer.xml");
+    }
+
+}

Propchange: servicemix/components/bindings/servicemix-snmp/trunk/src/test/java/org/apache/servicemix/snmp/SnmpTrapConsumerEndpointTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: servicemix/components/bindings/servicemix-snmp/trunk/src/test/resources/spring-trap-consumer.xml
URL: http://svn.apache.org/viewvc/servicemix/components/bindings/servicemix-snmp/trunk/src/test/resources/spring-trap-consumer.xml?rev=802775&view=auto
==============================================================================
--- servicemix/components/bindings/servicemix-snmp/trunk/src/test/resources/spring-trap-consumer.xml (added)
+++ servicemix/components/bindings/servicemix-snmp/trunk/src/test/resources/spring-trap-consumer.xml Mon Aug 10 13:01:48 2009
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+-->
+<beans xmlns:sm="http://servicemix.apache.org/config/1.0" 
+	   xmlns:snmp="http://servicemix.apache.org/snmp/1.0"
+       xmlns:test="urn:test">
+
+  <sm:container id="jbi" embedded="true" createMBeanServer="false">
+    
+    <sm:activationSpecs>
+    
+      <sm:activationSpec id="trap-consumer">
+      	<sm:component>
+      		<snmp:component>
+      			<snmp:endpoints>
+      				<snmp:trap-consumer service="test:snmp-service"
+      								   endpoint="trap-consumer"
+      								   targetService="test:receiver"
+      								   listenAddress="udp:127.0.0.1/1662">
+      				</snmp:trap-consumer>
+      			</snmp:endpoints>
+      		</snmp:component>
+      	</sm:component>
+      </sm:activationSpec>
+    
+      <sm:activationSpec id="receiver" service="test:receiver">
+        <sm:component>
+          <bean class="org.apache.servicemix.tck.ReceiverComponent" />
+        </sm:component>
+      </sm:activationSpec>
+      
+    </sm:activationSpecs>
+  </sm:container>
+
+</beans>

Propchange: servicemix/components/bindings/servicemix-snmp/trunk/src/test/resources/spring-trap-consumer.xml
------------------------------------------------------------------------------
    svn:mime-type = text/plain