1. /*
  2. * @(#)file SnmpSubBulkRequestHandler.java
  3. * @(#)author Sun Microsystems, Inc.
  4. * @(#)version 4.23
  5. * @(#)date 04/09/15
  6. *
  7. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  8. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  9. *
  10. */
  11. package com.sun.jmx.snmp.daemon;
  12. // java import
  13. //
  14. import java.util.Enumeration;
  15. import java.util.Vector;
  16. // jmx imports
  17. //
  18. import com.sun.jmx.snmp.SnmpPdu;
  19. import com.sun.jmx.snmp.SnmpVarBind;
  20. import com.sun.jmx.snmp.SnmpOid;
  21. import com.sun.jmx.snmp.SnmpValue;
  22. import com.sun.jmx.snmp.SnmpDefinitions;
  23. import com.sun.jmx.snmp.SnmpStatusException;
  24. import com.sun.jmx.snmp.SnmpEngine;
  25. // SNMP Runtime import
  26. //
  27. import com.sun.jmx.snmp.agent.SnmpMibAgent;
  28. import com.sun.jmx.snmp.agent.SnmpMibRequest;
  29. import com.sun.jmx.snmp.ThreadContext;
  30. import com.sun.jmx.snmp.daemon.SnmpAdaptorServer;
  31. import com.sun.jmx.snmp.internal.SnmpIncomingRequest;
  32. import com.sun.jmx.snmp.ThreadContext;
  33. class SnmpSubBulkRequestHandler extends SnmpSubRequestHandler {
  34. private SnmpAdaptorServer server = null;
  35. /**
  36. * The constuctor initialize the subrequest with the whole varbind list contained
  37. * in the original request.
  38. */
  39. protected SnmpSubBulkRequestHandler(SnmpEngine engine,
  40. SnmpAdaptorServer server,
  41. SnmpIncomingRequest incRequest,
  42. SnmpMibAgent agent,
  43. SnmpPdu req,
  44. int nonRepeat,
  45. int maxRepeat,
  46. int R) {
  47. super(engine, incRequest, agent, req);
  48. init(server, req, nonRepeat, maxRepeat, R);
  49. }
  50. /**
  51. * The constuctor initialize the subrequest with the whole varbind list contained
  52. * in the original request.
  53. */
  54. protected SnmpSubBulkRequestHandler(SnmpAdaptorServer server,
  55. SnmpMibAgent agent,
  56. SnmpPdu req,
  57. int nonRepeat,
  58. int maxRepeat,
  59. int R) {
  60. super(agent, req);
  61. init(server, req, nonRepeat, maxRepeat, R);
  62. }
  63. public void run() {
  64. size= varBind.size();
  65. try {
  66. // Invoke a getBulk operation
  67. //
  68. /* NPCTE fix for bugId 4492741, esc 0, 16-August-2001 */
  69. final ThreadContext oldContext =
  70. ThreadContext.push("SnmpUserData",data);
  71. try {
  72. if (isTraceOn()) {
  73. trace("run", "[" + Thread.currentThread() +
  74. "]:getBulk operation on " + agent.getMibName());
  75. }
  76. agent.getBulk(createMibRequest(varBind,version,data),
  77. nonRepeat, maxRepeat);
  78. } finally {
  79. ThreadContext.restore(oldContext);
  80. }
  81. /* end of NPCTE fix for bugId 4492741 */
  82. } catch(SnmpStatusException x) {
  83. errorStatus = x.getStatus() ;
  84. errorIndex= x.getErrorIndex();
  85. if (isDebugOn()) {
  86. debug("run", "[" + Thread.currentThread() +
  87. "]:an Snmp error occured during the operation");
  88. debug("run", x);
  89. }
  90. }
  91. catch(Exception x) {
  92. errorStatus = SnmpDefinitions.snmpRspGenErr ;
  93. if (isDebugOn()) {
  94. debug("run", "[" + Thread.currentThread() +
  95. "]:a generic error occured during the operation");
  96. debug("run", x);
  97. }
  98. }
  99. if (isTraceOn()) {
  100. trace("run", "[" + Thread.currentThread() +
  101. "]:operation completed");
  102. }
  103. }
  104. private void init(SnmpAdaptorServer server,
  105. SnmpPdu req,
  106. int nonRepeat,
  107. int maxRepeat,
  108. int R) {
  109. this.server = server;
  110. this.nonRepeat= nonRepeat;
  111. this.maxRepeat= maxRepeat;
  112. this.globalR= R;
  113. final int max= translation.length;
  114. final SnmpVarBind[] list= req.varBindList;
  115. final NonSyncVector nonSyncVarBind = ((NonSyncVector)varBind);
  116. for(int i=0; i < max; i++) {
  117. translation[i]= i;
  118. // we need to allocate a new SnmpVarBind. Otherwise the first
  119. // sub request will modify the list...
  120. //
  121. final SnmpVarBind newVarBind =
  122. new SnmpVarBind(list[i].oid, list[i].value);
  123. nonSyncVarBind.addNonSyncElement(newVarBind);
  124. }
  125. }
  126. /**
  127. * The method updates find out which element to use at update time. Handle oid overlapping as well
  128. */
  129. private SnmpVarBind findVarBind(SnmpVarBind element,
  130. SnmpVarBind result) {
  131. if (element == null) return null;
  132. if (result.oid == null) {
  133. return element;
  134. }
  135. if (element.value == SnmpVarBind.endOfMibView) return result;
  136. if (result.value == SnmpVarBind.endOfMibView) return element;
  137. final SnmpValue val = result.value;
  138. int comp = element.oid.compareTo(result.oid);
  139. if(isDebugOn()) {
  140. trace("findVarBind","Comparing OID element : " + element.oid +
  141. " with result : " + result.oid);
  142. trace("findVarBind","Values element : " + element.value +
  143. " result : " + result.value);
  144. }
  145. if (comp < 0) {
  146. // Take the smallest (lexicographically)
  147. //
  148. return element;
  149. }
  150. else {
  151. if(comp == 0) {
  152. // Must compare agent used for reply
  153. // Take the deeper within the reply
  154. if(isDebugOn()) {
  155. trace("findVarBind"," oid overlapping. Oid : " +
  156. element.oid + "value :" + element.value);
  157. trace("findVarBind","Already present varBind : " +
  158. result);
  159. }
  160. SnmpOid oid = result.oid;
  161. SnmpMibAgent deeperAgent = server.getAgentMib(oid);
  162. if(isDebugOn())
  163. trace("findVarBind","Deeper agent : " + deeperAgent);
  164. if(deeperAgent == agent) {
  165. if(isDebugOn())
  166. trace("updateResult","The current agent is the deeper one. Update the value with the current one");
  167. return element;
  168. } else {
  169. if(isDebugOn())
  170. trace("updateResult","Current is not the deeper, return the previous one.");
  171. return result;
  172. }
  173. /*
  174. Vector v = new Vector();
  175. SnmpMibRequest getReq = createMibRequest(v,
  176. version,
  177. null);
  178. SnmpVarBind realValue = new SnmpVarBind(oid);
  179. getReq.addVarBind(realValue);
  180. try {
  181. deeperAgent.get(getReq);
  182. } catch(SnmpStatusException e) {
  183. e.printStackTrace();
  184. }
  185. if(isDebugOn())
  186. trace("findVarBind", "Biggest priority value is : " +
  187. realValue.value);
  188. return realValue;
  189. */
  190. }
  191. else {
  192. if(isDebugOn())
  193. trace("findVarBind",
  194. "The right varBind is the already present one");
  195. return result;
  196. }
  197. }
  198. }
  199. /**
  200. * The method updates a given var bind list with the result of a
  201. * previsouly invoked operation.
  202. * Prior to calling the method, one must make sure that the operation was
  203. * successful. As such the method getErrorIndex or getErrorStatus should be
  204. * called.
  205. */
  206. protected void updateResult(SnmpVarBind[] result) {
  207. // we can assume that the run method is over ...
  208. //
  209. final Enumeration e= varBind.elements();
  210. final int max= result.length;
  211. // First go through all the values once ...
  212. for(int i=0; i < size; i++) {
  213. // May be we should control the position ...
  214. //
  215. if (e.hasMoreElements() == false)
  216. return;
  217. // bugId 4641694: must check position in order to avoid
  218. // ArrayIndexOutOfBoundException
  219. final int pos=translation[i];
  220. if (pos >= max) {
  221. debug("updateResult","Position `"+pos+"' is out of bound...");
  222. continue;
  223. }
  224. final SnmpVarBind element= (SnmpVarBind) e.nextElement();
  225. if (element == null) continue;
  226. if (isDebugOn())
  227. trace("updateResult", "Non repeaters Current element : " +
  228. element + " from agent : " + agent);
  229. final SnmpVarBind res = findVarBind(element,result[pos]);
  230. if(res == null) continue;
  231. result[pos] = res;
  232. }
  233. // Now update the values which have been repeated
  234. // more than once.
  235. int localR= size - nonRepeat;
  236. for (int i = 2 ; i <= maxRepeat ; i++) {
  237. for (int r = 0 ; r < localR ; r++) {
  238. final int pos = (i-1)* globalR + translation[nonRepeat + r] ;
  239. if (pos >= max)
  240. return;
  241. if (e.hasMoreElements() ==false)
  242. return;
  243. final SnmpVarBind element= (SnmpVarBind) e.nextElement();
  244. if (element == null) continue;
  245. if (isDebugOn())
  246. trace("updateResult", "Repeaters Current element : " +
  247. element + " from agent : " + agent);
  248. final SnmpVarBind res = findVarBind(element, result[pos]);
  249. if(res == null) continue;
  250. result[pos] = res;
  251. }
  252. }
  253. }
  254. protected String makeDebugTag() {
  255. return "SnmpSubBulkRequestHandler";
  256. }
  257. // PROTECTED VARIABLES
  258. //------------------
  259. /**
  260. * Specific to the sub request
  261. */
  262. protected int nonRepeat=0;
  263. protected int maxRepeat=0;
  264. /**
  265. * R as defined in RCF 1902 for the global request the sub-request is associated to.
  266. */
  267. protected int globalR=0;
  268. protected int size=0;
  269. }