001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.snmp;
018    
019    import org.apache.camel.Exchange;
020    import org.apache.camel.Processor;
021    import org.apache.camel.impl.ScheduledPollConsumer;
022    import org.apache.commons.logging.Log;
023    import org.apache.commons.logging.LogFactory;
024    import org.snmp4j.CommunityTarget;
025    import org.snmp4j.PDU;
026    import org.snmp4j.Snmp;
027    import org.snmp4j.TransportMapping;
028    import org.snmp4j.event.ResponseEvent;
029    import org.snmp4j.event.ResponseListener;
030    import org.snmp4j.mp.MPv3;
031    import org.snmp4j.security.SecurityModels;
032    import org.snmp4j.security.SecurityProtocols;
033    import org.snmp4j.security.USM;
034    import org.snmp4j.smi.Address;
035    import org.snmp4j.smi.GenericAddress;
036    import org.snmp4j.smi.OID;
037    import org.snmp4j.smi.OctetString;
038    import org.snmp4j.smi.VariableBinding;
039    import org.snmp4j.transport.DefaultUdpTransportMapping;
040    
041    public class SnmpOIDPoller extends ScheduledPollConsumer implements ResponseListener {
042    
043        private static final transient Log LOG = LogFactory.getLog(SnmpOIDPoller.class);
044    
045        private Address targetAddress;
046        private TransportMapping transport;
047        private Snmp snmp;
048        private USM usm;
049        private CommunityTarget target;
050        private PDU pdu;
051        private SnmpEndpoint endpoint;
052    
053        public SnmpOIDPoller(SnmpEndpoint endpoint, Processor processor) {
054            super(endpoint, processor);
055            this.endpoint = endpoint;
056            // convert delay from seconds to millis
057            setDelay(endpoint.getDelay() * 1000);
058        }
059    
060        @Override
061        protected void doStart() throws Exception {
062            super.doStart();
063    
064            LOG.debug("Activating oid poller");
065            this.targetAddress = GenericAddress.parse(this.endpoint.getAddress());
066            this.transport = new DefaultUdpTransportMapping();
067            this.snmp = new Snmp(this.transport);
068            this.usm = new USM(SecurityProtocols.getInstance(), new OctetString(MPv3.createLocalEngineID()), 0);
069            SecurityModels.getInstance().addSecurityModel(usm);
070    
071            // setting up target
072            target = new CommunityTarget();
073            target.setCommunity(new OctetString(this.endpoint.getSnmpCommunity()));
074            target.setAddress(targetAddress);
075            target.setRetries(this.endpoint.getRetries());
076            target.setTimeout(this.endpoint.getTimeout());
077            target.setVersion(this.endpoint.getSnmpVersion());
078    
079            // creating PDU
080            this.pdu = new PDU();
081            // listen to the transport
082            this.transport.listen();
083        }
084    
085        @Override
086        protected void doStop() throws Exception {
087            // stop listening to the transport
088            if (this.transport.isListening()) {
089                this.transport.close();
090            }
091    
092            super.doStop();
093        }
094    
095        @Override
096        protected void poll() throws Exception {
097            this.pdu.clear();
098            this.pdu.setType(PDU.GET);
099    
100            // prepare the request items
101            for (OID oid : this.endpoint.getOids()) {
102                this.pdu.add(new VariableBinding(oid));
103            }
104    
105            // send the request
106            snmp.send(pdu, target, null, this);
107        }
108    
109        public void onResponse(ResponseEvent event) {
110            // Always cancel async request when response has been received
111            // otherwise a memory leak is created! Not canceling a request
112            // immediately can be useful when sending a request to a broadcast
113            // address.
114            ((Snmp)event.getSource()).cancel(event.getRequest(), this);
115    
116            // check for valid response
117            if (event.getRequest() == null || event.getResponse() == null) {
118                // ignore null requests/responses
119                LOG.debug("Received invalid snmp event. Request: " + event.getRequest() + " / Response: " + event.getResponse());
120                return;
121            }
122            
123            PDU pdu = event.getResponse();
124            processPDU(pdu);
125        }
126    
127        /**
128         * processes the pdu message
129         * 
130         * @param pdu the pdu
131         */
132        public void processPDU(PDU pdu) {
133            if (LOG.isDebugEnabled()) {
134                LOG.debug("Received response event for " + this.endpoint.getAddress() + " : " + pdu);
135            }
136            Exchange exchange = endpoint.createExchange(pdu);
137            try {
138                getProcessor().process(exchange);
139            } catch (Exception ex) {
140                exchange.setException(ex);
141            }
142        }
143    
144        /** * @return Returns the target.
145         */
146        public CommunityTarget getTarget() {
147            return this.target;
148        }
149    
150        /**
151         * @param target The target to set.
152         */
153        public void setTarget(CommunityTarget target) {
154            this.target = target;
155        }
156    }