bulk
来源:互联网 发布:nginx lua 环境搭建 编辑:程序博客网 时间:2024/06/06 20:32
/*_############################################################################
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 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 userObject, TreeListener listener) {
105 walk(target, rootOID, rootOID, userObject, listener);
106 }
107
108 private void walk(Target target, OID rootOID,
109 OID startOID, Object 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 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 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