KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snmp4j > util > TreeUtils


1 /*_############################################################################
2   _##
3   _## SNMP4J - TreeUtils.java
4   _##
5   _## Copyright 2003-2007 Frank Fock and Jochen Katz (SNMP4J.org)
6   _##
7   _## Licensed under the Apache License, Version 2.0 (the "License");
8   _## you may not use this file except in compliance with the License.
9   _## You may obtain a copy of the License at
10   _##
11   _## http://www.apache.org/licenses/LICENSE-2.0
12   _##
13   _## Unless required by applicable law or agreed to in writing, software
14   _## distributed under the License is distributed on an "AS IS" BASIS,
15   _## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   _## See the License for the specific language governing permissions and
17   _## limitations under the License.
18   _##
19   _##########################################################################*/

20
21 package org.snmp4j.util;
22
23 import java.io.*;
24 import java.util.*;
25
26 import org.snmp4j.*;
27 import org.snmp4j.event.*;
28 import org.snmp4j.log.*;
29 import org.snmp4j.mp.*;
30 import org.snmp4j.smi.*;
31
32 public class TreeUtils extends AbstractSnmpUtility {
33
34   private static final LogAdapter logger =
35       LogFactory.getLogger(TreeUtils.class);
36
37   private int maxRepetitions = 10;
38
39   /**
40    * Creates a <code>TreeUtils</code> instance. The created instance is thread
41    * safe as long as the supplied <code>Session</code> and
42    * <code>PDUFactory</code> are thread safe.
43    *
44    * @param snmpSession
45    * a SNMP <code>Session</code> instance.
46    * @param pduFactory
47    * a <code>PDUFactory</code> instance that creates the PDU that are used
48    * by this instance to retrieve MIB tree data using GETBULK/GETNEXT
49    * operations.
50    */

51   public TreeUtils(Session snmpSession, PDUFactory pduFactory) {
52     super(snmpSession, pduFactory);
53   }
54
55   /**
56    * Gets a subtree with GETNEXT (SNMPv1) or GETBULK (SNMP2c, SNMPv3) operations
57    * from the specified target synchronously.
58    *
59    * @param target
60    * a <code>Target</code> that specifies the target command responder
61    * including its network transport address.
62    * @param rootOID
63    * the OID that specifies the root of the sub-tree to retrieve
64    * (not included).
65    * @return
66    * a possibly empty List of <code>TreeEvent</code> instances where each
67    * instance carries zero or more values (or an error condition)
68    * in depth-first-order.
69    */

70   public List getSubtree(Target target, OID rootOID) {
71     List l = new LinkedList();
72     TreeListener listener = new InternalTreeListener(l);
73     synchronized (listener) {
74       walk(target, rootOID, rootOID, null, listener);
75       try {
76         listener.wait();
77       }
78       catch (InterruptedException JavaDoc ex) {
79         logger.warn("Tree retrieval interrupted: " + ex.getMessage());
80       }
81     }
82     return l;
83   }
84
85   /**
86    * Gets a subtree with GETNEXT (SNMPv1) or GETBULK (SNMP2c, SNMPv3) operations
87    * from the specified target asynchronously.
88    *
89    * @param target
90    * a <code>Target</code> that specifies the target command responder
91    * including its network transport address.
92    * @param rootOID
93    * the OID that specifies the root of the sub-tree to retrieve
94    * (not included).
95    * @param userObject
96    * an optional user object that will be transparently handed over to the
97    * supplied <code>TreeListener</code>.
98    * @param listener
99    * the <code>TreeListener</code> that processes the {@link TreeEvent}s
100    * generated by this method. Each event object may carry zero or more
101    * object instances from the sub-tree in depth-first-order.
102    */

103   public void getSubtree(Target target, OID rootOID,
104                          Object JavaDoc userObject, TreeListener listener) {
105     walk(target, rootOID, rootOID, userObject, listener);
106   }
107
108   private void walk(Target target, OID rootOID,
109                     OID startOID, Object JavaDoc userObject,
110                     TreeListener listener) {
111     PDU request = pduFactory.createPDU(target);
112     request.add(new VariableBinding(startOID));
113     if (target.getVersion() == SnmpConstants.version1) {
114       request.setType(PDU.GETNEXT);
115     }
116     else {
117       request.setType(PDU.GETBULK);
118       request.setMaxRepetitions(maxRepetitions);
119     }
120     TreeRequest treeRequest =
121         new TreeRequest(listener, rootOID, target, userObject, request);
122     treeRequest.send();
123   }
124
125   /**
126    * Sets the maximum number of the variable bindings per <code>TreeEvent</code>
127    * returned by this instance.
128    * @param maxRepetitions
129    * the maximum repetitions used for GETBULK requests. For SNMPv1 this
130    * values has no effect (it is then implicitly one).
131    */

132   public void setMaxRepetitions(int maxRepetitions) {
133     this.maxRepetitions = maxRepetitions;
134   }
135
136   /**
137    * Gets the maximum number of the variable bindings per <code>TreeEvent</code>
138    * returned by this instance.
139    * @return
140    * the maximum repetitions used for GETBULK requests. For SNMPv1 this
141    * values has no effect (it is then implicitly one).
142    */

143   public int getMaxRepetitions() {
144     return maxRepetitions;
145   }
146
147   class TreeRequest implements ResponseListener {
148
149     private TreeListener listener;
150     private Object JavaDoc userObject;
151     private PDU request;
152     private OID rootOID;
153     private Target target;
154
155     public TreeRequest(TreeListener listener, OID rootOID, Target target,
156                        Object JavaDoc userObject, PDU request) {
157       this.listener = listener;
158       this.userObject = userObject;
159       this.request = request;
160       this.rootOID = rootOID;
161       this.target = target;
162     }
163
164     public void send() {
165       try {
166         session.send(request, target, null, this);
167       }
168       catch (IOException iox) {
169         listener.finished(new TreeEvent(this, userObject, iox));
170       }
171     }
172
173     public void onResponse(ResponseEvent event) {
174       session.cancel(event.getRequest(), this);
175       PDU respPDU = event.getResponse();
176       if (respPDU == null) {
177         listener.finished(new TreeEvent(this, userObject,
178                                         RetrievalEvent.STATUS_TIMEOUT));
179       }
180       else if (respPDU.getErrorStatus() != 0) {
181         listener.finished(new TreeEvent(this, userObject,
182                                         respPDU.getErrorStatus()));
183       }
184       else if (respPDU.getType() == PDU.REPORT) {
185         listener.finished(new TreeEvent(this, userObject, respPDU));
186       }
187       else {
188         List l = new ArrayList(respPDU.size());
189         OID lastOID = request.get(0).getOid();
190         boolean finished = false;
191         for (int i = 0; (!finished) && (i < respPDU.size()); i++) {
192           VariableBinding vb = respPDU.get(i);
193           if ((vb.getOid() == null) ||
194               (vb.getOid().size() < rootOID.size()) ||
195               (rootOID.leftMostCompare(rootOID.size(), vb.getOid()) != 0)) {
196             finished = true;
197           }
198           else if (Null.isExceptionSyntax(vb.getVariable().getSyntax())) {
199             finished = true;
200           }
201           else if (vb.getOid().compareTo(lastOID) <= 0) {
202             listener.finished(new TreeEvent(this, userObject,
203                                             RetrievalEvent.STATUS_WRONG_ORDER));
204             finished = true;
205             break;
206           }
207           else {
208             lastOID = vb.getOid();
209             l.add(vb);
210           }
211         }
212         if (respPDU.size() == 0) {
213           finished = true;
214         }
215         VariableBinding[] vbs =
216             (VariableBinding[]) l.toArray(new VariableBinding[0]);
217         if (finished) {
218           listener.finished(new TreeEvent(this, userObject, vbs));
219         }
220         else {
221           if (listener.next(new TreeEvent(this, userObject, vbs))) {
222             VariableBinding next =
223                 (VariableBinding) respPDU.get(respPDU.size() - 1).clone();
224             next.setVariable(new Null());
225             request.set(0, next);
226             request.setRequestID(new Integer32(0));
227             send();
228             return;
229           }
230           else {
231             finished = true;
232           }
233         }
234       }
235       synchronized (listener) {
236         listener.notify();
237       }
238     }
239   }
240
241   class InternalTreeListener implements TreeListener {
242
243     private List collectedEvents;
244
245     public InternalTreeListener(List eventList) {
246       collectedEvents = eventList;
247     }
248
249     public synchronized boolean next(TreeEvent event) {
250       collectedEvents.add(event);
251       return true;
252     }
253
254     public synchronized void finished(TreeEvent event) {
255       collectedEvents.add(event);
256       notify();
257     }
258
259     public List getCollectedEvents() {
260       return collectedEvents;
261     }
262   }
263 }
264
Popular Tags