blob: 31ec77f1b83101bd776791b6cfa9c1c0ac89bf6f [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26
27package com.sun.jmx.snmp.daemon;
28
29
30
31// java import
32//
33import java.util.Enumeration;
34import java.util.Vector;
35import java.util.logging.Level;
36// jmx imports
37//
38import com.sun.jmx.snmp.SnmpPdu;
39import com.sun.jmx.snmp.SnmpVarBind;
40import com.sun.jmx.snmp.SnmpOid;
41import com.sun.jmx.snmp.SnmpValue;
42import com.sun.jmx.snmp.SnmpDefinitions;
43import com.sun.jmx.snmp.SnmpStatusException;
44import com.sun.jmx.snmp.SnmpEngine;
45// SNMP Runtime import
46//
47import static com.sun.jmx.defaults.JmxProperties.SNMP_ADAPTOR_LOGGER;
48import com.sun.jmx.snmp.agent.SnmpMibAgent;
49import com.sun.jmx.snmp.agent.SnmpMibRequest;
50import com.sun.jmx.snmp.ThreadContext;
51import com.sun.jmx.snmp.daemon.SnmpAdaptorServer;
52import com.sun.jmx.snmp.internal.SnmpIncomingRequest;
53import com.sun.jmx.snmp.ThreadContext;
54
55class SnmpSubBulkRequestHandler extends SnmpSubRequestHandler {
56 private SnmpAdaptorServer server = null;
57
58 /**
59 * The constuctor initialize the subrequest with the whole varbind list contained
60 * in the original request.
61 */
62 protected SnmpSubBulkRequestHandler(SnmpEngine engine,
63 SnmpAdaptorServer server,
64 SnmpIncomingRequest incRequest,
65 SnmpMibAgent agent,
66 SnmpPdu req,
67 int nonRepeat,
68 int maxRepeat,
69 int R) {
70 super(engine, incRequest, agent, req);
71 init(server, req, nonRepeat, maxRepeat, R);
72 }
73
74 /**
75 * The constuctor initialize the subrequest with the whole varbind list contained
76 * in the original request.
77 */
78 protected SnmpSubBulkRequestHandler(SnmpAdaptorServer server,
79 SnmpMibAgent agent,
80 SnmpPdu req,
81 int nonRepeat,
82 int maxRepeat,
83 int R) {
84 super(agent, req);
85 init(server, req, nonRepeat, maxRepeat, R);
86 }
87
88 public void run() {
89
90 size= varBind.size();
91
92 try {
93 // Invoke a getBulk operation
94 //
95 /* NPCTE fix for bugId 4492741, esc 0, 16-August-2001 */
96 final ThreadContext oldContext =
97 ThreadContext.push("SnmpUserData",data);
98 try {
99 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
100 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
101 "run", "[" + Thread.currentThread() +
102 "]:getBulk operation on " + agent.getMibName());
103 }
104 agent.getBulk(createMibRequest(varBind,version,data),
105 nonRepeat, maxRepeat);
106 } finally {
107 ThreadContext.restore(oldContext);
108 }
109 /* end of NPCTE fix for bugId 4492741 */
110
111 } catch(SnmpStatusException x) {
112 errorStatus = x.getStatus() ;
113 errorIndex= x.getErrorIndex();
114 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
115 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpSubRequestHandler.class.getName(),
116 "run", "[" + Thread.currentThread() +
117 "]:an Snmp error occured during the operation", x);
118 }
119 }
120 catch(Exception x) {
121 errorStatus = SnmpDefinitions.snmpRspGenErr ;
122 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
123 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpSubRequestHandler.class.getName(),
124 "run", "[" + Thread.currentThread() +
125 "]:a generic error occured during the operation", x);
126 }
127 }
128 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
129 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
130 "run", "[" + Thread.currentThread() +
131 "]:operation completed");
132 }
133 }
134
135 private void init(SnmpAdaptorServer server,
136 SnmpPdu req,
137 int nonRepeat,
138 int maxRepeat,
139 int R) {
140 this.server = server;
141 this.nonRepeat= nonRepeat;
142 this.maxRepeat= maxRepeat;
143 this.globalR= R;
144
145 final int max= translation.length;
146 final SnmpVarBind[] list= req.varBindList;
147 final NonSyncVector<SnmpVarBind> nonSyncVarBind =
148 ((NonSyncVector<SnmpVarBind>)varBind);
149 for(int i=0; i < max; i++) {
150 translation[i]= i;
151 // we need to allocate a new SnmpVarBind. Otherwise the first
152 // sub request will modify the list...
153 //
154 final SnmpVarBind newVarBind =
155 new SnmpVarBind(list[i].oid, list[i].value);
156 nonSyncVarBind.addNonSyncElement(newVarBind);
157 }
158 }
159
160 /**
161 * The method updates find out which element to use at update time. Handle oid overlapping as well
162 */
163 private SnmpVarBind findVarBind(SnmpVarBind element,
164 SnmpVarBind result) {
165
166 if (element == null) return null;
167
168 if (result.oid == null) {
169 return element;
170 }
171
172 if (element.value == SnmpVarBind.endOfMibView) return result;
173
174 if (result.value == SnmpVarBind.endOfMibView) return element;
175
176 final SnmpValue val = result.value;
177
178 int comp = element.oid.compareTo(result.oid);
179 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
180 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
181 "findVarBind","Comparing OID element : " + element.oid +
182 " with result : " + result.oid);
183 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
184 "findVarBind","Values element : " + element.value +
185 " result : " + result.value);
186 }
187 if (comp < 0) {
188 // Take the smallest (lexicographically)
189 //
190 return element;
191 }
192 else {
193 if(comp == 0) {
194 // Must compare agent used for reply
195 // Take the deeper within the reply
196 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
197 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
198 "findVarBind"," oid overlapping. Oid : " +
199 element.oid + "value :" + element.value);
200 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
201 "findVarBind","Already present varBind : " +
202 result);
203 }
204 SnmpOid oid = result.oid;
205 SnmpMibAgent deeperAgent = server.getAgentMib(oid);
206
207 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
208 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
209 "findVarBind","Deeper agent : " + deeperAgent);
210 }
211 if(deeperAgent == agent) {
212 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
213 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
214 "findVarBind","The current agent is the deeper one. Update the value with the current one");
215 }
216 return element;
217 } else {
218 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
219 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
220 "findVarBind","The current agent is not the deeper one. return the previous one.");
221 }
222 return result;
223 }
224
225 /*
226 Vector v = new Vector();
227 SnmpMibRequest getReq = createMibRequest(v,
228 version,
229 null);
230 SnmpVarBind realValue = new SnmpVarBind(oid);
231 getReq.addVarBind(realValue);
232 try {
233 deeperAgent.get(getReq);
234 } catch(SnmpStatusException e) {
235 e.printStackTrace();
236 }
237
238 if(isDebugOn())
239 trace("findVarBind", "Biggest priority value is : " +
240 realValue.value);
241
242 return realValue;
243 */
244
245 }
246 else {
247 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
248 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
249 "findVarBind","The right varBind is the already present one");
250 }
251 return result;
252 }
253 }
254 }
255 /**
256 * The method updates a given var bind list with the result of a
257 * previsouly invoked operation.
258 * Prior to calling the method, one must make sure that the operation was
259 * successful. As such the method getErrorIndex or getErrorStatus should be
260 * called.
261 */
262 protected void updateResult(SnmpVarBind[] result) {
263 // we can assume that the run method is over ...
264 //
265
266 final Enumeration e= varBind.elements();
267 final int max= result.length;
268
269 // First go through all the values once ...
270 for(int i=0; i < size; i++) {
271 // May be we should control the position ...
272 //
273 if (e.hasMoreElements() == false)
274 return;
275
276 // bugId 4641694: must check position in order to avoid
277 // ArrayIndexOutOfBoundException
278 final int pos=translation[i];
279 if (pos >= max) {
280 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) {
281 SNMP_ADAPTOR_LOGGER.logp(Level.FINEST, SnmpSubRequestHandler.class.getName(),
282 "updateResult","Position '"+pos+"' is out of bound...");
283 }
284 continue;
285 }
286
287 final SnmpVarBind element= (SnmpVarBind) e.nextElement();
288
289 if (element == null) continue;
290 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
291 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
292 "updateResult","Non repeaters Current element : " +
293 element + " from agent : " + agent);
294 }
295 final SnmpVarBind res = findVarBind(element,result[pos]);
296
297 if(res == null) continue;
298
299 result[pos] = res;
300 }
301
302 // Now update the values which have been repeated
303 // more than once.
304 int localR= size - nonRepeat;
305 for (int i = 2 ; i <= maxRepeat ; i++) {
306 for (int r = 0 ; r < localR ; r++) {
307 final int pos = (i-1)* globalR + translation[nonRepeat + r] ;
308 if (pos >= max)
309 return;
310 if (e.hasMoreElements() ==false)
311 return;
312 final SnmpVarBind element= (SnmpVarBind) e.nextElement();
313
314 if (element == null) continue;
315 if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) {
316 SNMP_ADAPTOR_LOGGER.logp(Level.FINER, SnmpSubRequestHandler.class.getName(),
317 "updateResult","Repeaters Current element : " +
318 element + " from agent : " + agent);
319 }
320 final SnmpVarBind res = findVarBind(element, result[pos]);
321
322 if(res == null) continue;
323
324 result[pos] = res;
325 }
326 }
327 }
328
329 // PROTECTED VARIABLES
330 //------------------
331
332 /**
333 * Specific to the sub request
334 */
335 protected int nonRepeat=0;
336
337 protected int maxRepeat=0;
338
339 /**
340 * R as defined in RCF 1902 for the global request the sub-request is associated to.
341 */
342 protected int globalR=0;
343
344 protected int size=0;
345}