1 22 23 24 package org.snmp4j.agent.agentx.master; 25 26 import java.util.Collection ; 27 import java.util.Iterator ; 28 import java.util.LinkedList ; 29 30 import org.snmp4j.PDU; 31 import org.snmp4j.agent.MOServer; 32 import org.snmp4j.agent.agentx.AgentXProtocol; 33 import org.snmp4j.agent.request.SnmpRequest; 34 import org.snmp4j.agent.request.SnmpSubRequest; 35 import org.snmp4j.log.LogAdapter; 36 import org.snmp4j.log.LogFactory; 37 import org.snmp4j.smi.VariableBinding; 38 import org.snmp4j.agent.DefaultMOScope; 39 import org.snmp4j.agent.ManagedObject; 40 import org.snmp4j.agent.MOScope; 41 import org.snmp4j.agent.agentx.AgentXRegion; 42 43 public class AgentXQueue { 44 45 private static final LogAdapter LOGGER = 46 LogFactory.getLogger(AgentXQueue.class); 47 48 private LinkedList queue = new LinkedList (); 49 private MOServer server; 50 51 public AgentXQueue() { 52 } 53 54 public void setServer4BulkOptimization(MOServer server) { 55 this.server = server; 56 } 57 58 public MOServer getServer4BulkOptimization() { 59 return this.server; 60 } 61 62 public synchronized boolean add(VariableBinding vb, 63 SnmpSubRequest subRequest, 64 AgentXRegEntry entry) { 65 SnmpRequest request = (SnmpRequest) subRequest.getRequest(); 66 AgentXPendingSet pending = 67 (AgentXPendingSet) get(entry.getSession().getSessionID(), 68 request.getTransactionID()); 69 if (pending == null) { 70 pending = new AgentXPendingSet(entry, subRequest.getSnmpRequest()); 71 insertIntoQueue(request.getTransactionID(), pending); 72 } 73 if (!pending.isPending()) { 74 if (LOGGER.isDebugEnabled()) { 75 LOGGER.debug("Variable binding " + vb + 76 " not addded because AgentX request " + pending + 77 " is waiting for response"); 78 } 79 return false; 80 } 81 pending.add(subRequest, vb); 82 return true; 83 } 84 85 private synchronized void insertIntoQueue(int transactionID, 86 AgentXPending pending) { 87 AgentXRegEntry reg = pending.getRegistration(); 88 int timeout = reg.getTimeout(); 89 if (timeout == 0) { 90 timeout = reg.getSession().getTimeout() & 0xFF; 91 } 92 pending.setTimeout(timeout); 93 94 AgentXQueueEntry entry = getQueueEntry(transactionID, false); 95 if (entry == null) { 96 entry = new AgentXQueueEntry(transactionID); 97 queue.add(entry); 98 } 99 entry.addEntry(pending); 100 } 101 102 public synchronized boolean add(AgentXSearchRange searchRange, 103 AgentXRegEntry entry, boolean repeater) { 104 SnmpRequest request = 105 (SnmpRequest) searchRange.getReferenceSubRequest().getRequest(); 106 AgentXPendingGet pending = 107 (AgentXPendingGet) get(entry.getSession().getSessionID(), 108 request.getTransactionID()); 109 if (pending == null) { 110 if ((server != null) && 112 (request.getInitiatingEvent().getPDU().getType() == PDU.GETBULK)) { 113 optimizeSearchRange(searchRange, entry); 114 } 115 pending = new AgentXPendingGet(entry, request, searchRange); 116 insertIntoQueue(request.getTransactionID(), pending); 117 } 118 else if (pending.isPending()) { 119 switch (request.getInitiatingEvent().getPDU().getType()) { 120 case PDU.GETBULK: { 121 for (Iterator it = pending.getSearchRanges().iterator(); it.hasNext();) { 122 AgentXSearchRange psr = (AgentXSearchRange) it.next(); 123 if ((searchRange.getReferenceSubRequest().getIndex() - 124 psr.getReferenceSubRequest().getIndex()) % 125 request.getRepeaterCount() == 0) { 126 if (LOGGER.isDebugEnabled()) { 129 LOGGER.debug("Repetition not added because of pending AgentX"+ 130 " processing of "+pending+" and repetition "+psr); 131 } 132 return false; 133 } 134 } 135 if (server != null) { 137 optimizeSearchRange(searchRange, entry); 138 } 139 break; 140 } 141 default: { 142 } 144 } 145 pending.addSearchRange(searchRange); 146 } 147 else { 148 if (LOGGER.isDebugEnabled()) { 149 LOGGER.debug("Search range " + searchRange + 150 " not addded because AgentX request " + pending + 151 " is not pending"); 152 } 153 return false; 154 } 155 if (!repeater) { 156 pending.incNonRepeater(); 157 } 158 return true; 159 } 160 161 protected void optimizeSearchRange(AgentXSearchRange searchRange, 162 AgentXRegEntry entry) { 163 DefaultMOScope scope = new DefaultMOScope(searchRange.getUpperBound(), 164 !searchRange.isUpperIncluded(), 165 null, false); 166 AgentXNodeQuery query = 167 new AgentXNodeQuery(entry.getContext(), scope, 168 AgentXNodeQuery.QUERY_ALL); 169 MOScope requestScope = searchRange.getReferenceSubRequest().getScope(); 170 for (ManagedObject node = server.lookup(query); 171 (node instanceof AgentXNode); 172 node = server.lookup(nextQuery(query, (AgentXNode)node))) 173 { 174 AgentXRegEntry activeReg = ((AgentXNode)node).getActiveRegistration(); 175 MOScope region = node.getScope(); 176 if ((activeReg != null) && 177 (activeReg.getSession().equals(entry.getSession()))) { 178 if ((requestScope.getUpperBound() != null) && 179 (requestScope.getUpperBound(). 180 compareTo(region.getUpperBound()) <= 0)) { 181 searchRange.setUpperBound(requestScope.getUpperBound()); 182 searchRange.setUpperIncluded(requestScope.isUpperIncluded()); 183 break; 184 } 185 searchRange.setUpperBound(region.getUpperBound()); 186 searchRange.setUpperIncluded(region.isUpperIncluded()); 187 } 188 else { 189 if ((searchRange.getUpperBound() == null) || 190 (searchRange.getUpperBound().compareTo(region.getLowerBound()) >= 0)) { 191 searchRange.setUpperBound(region.getLowerBound()); 192 searchRange.setUpperIncluded(!region.isLowerIncluded()); 193 } 194 break; 195 } 196 } 197 if (LOGGER.isDebugEnabled()) { 198 LOGGER.debug("Optimized upper bound for bulk AgentX request to "+ 199 searchRange); 200 } 201 } 202 203 private static AgentXNodeQuery nextQuery(AgentXNodeQuery lastQuery, 204 AgentXNode lastNode) { 205 if (lastNode != null) { 206 lastQuery.getMutableScope().setLowerBound( 207 lastNode.getScope().getUpperBound()); 208 lastQuery.getMutableScope().setLowerIncluded(false); 209 } 210 return lastQuery; 211 } 212 213 224 public synchronized AgentXPending get(int sessionID, int transactionID) { 225 AgentXQueueEntry entry = getQueueEntry(transactionID, false); 226 if (entry != null) { 227 AgentXPending p = entry.get(sessionID, false); 228 return p; 229 } 230 return null; 231 } 232 233 245 public synchronized AgentXPending remove(int sessionID, int transactionID) { 246 AgentXQueueEntry entry = getQueueEntry(transactionID, false); 247 if (entry != null) { 248 return entry.get(sessionID, true); 249 } 250 return null; 251 } 252 253 254 262 public synchronized AgentXQueueEntry get(int transactionID) { 263 return getQueueEntry(transactionID, false); 264 } 265 266 271 public synchronized void removeAll(int transactionID) { 272 getQueueEntry(transactionID, true); 273 } 274 275 private AgentXQueueEntry getQueueEntry(int transactionID, boolean remove) { 276 for (Iterator it = queue.iterator(); it.hasNext(); ) { 277 AgentXQueueEntry entry = (AgentXQueueEntry) it.next(); 278 if (entry.transactionID == transactionID) { 279 if (remove) { 280 it.remove(); 281 } 282 return entry; 283 } 284 } 285 return null; 286 } 287 288 public class AgentXQueueEntry implements Comparable { 289 290 private int transactionID; 291 private LinkedList requests; 292 private int minTimeout = AgentXProtocol.MAX_TIMEOUT_SECONDS; 293 private long timestamp = 0; 294 295 public AgentXQueueEntry(int transactionID) { 296 this.transactionID = transactionID; 297 this.requests = new LinkedList (); 298 } 299 300 public synchronized final void addEntry(AgentXPending pendingRequest) { 301 this.requests.add(pendingRequest); 302 if (minTimeout > pendingRequest.getTimeout()) { 303 minTimeout = pendingRequest.getTimeout(); 304 } 305 } 306 307 public final void updateTimestamp() { 308 this.timestamp = System.currentTimeMillis(); 309 } 310 311 public final long getTimestamp() { 312 return timestamp; 313 } 314 315 public final int getMinTimeout() { 316 return minTimeout; 317 } 318 319 public boolean equals(Object obj) { 320 if (obj instanceof AgentXQueueEntry) { 321 AgentXQueueEntry other = (AgentXQueueEntry)obj; 322 return ((transactionID == other.transactionID)); 323 } 324 return false; 325 } 326 327 public int hashCode() { 328 return transactionID; 329 } 330 331 public String toString() { 332 return "AgentXQueueEntry[transactionID="+transactionID+",requests="+ 333 requests+"]"; 334 } 335 336 public int compareTo(Object o) { 337 AgentXQueueEntry other = (AgentXQueueEntry)o; 338 return transactionID - other.transactionID; 339 } 340 341 public final synchronized AgentXPending get(int sessionID, boolean remove) { 342 for (Iterator it = requests.iterator(); it.hasNext(); ) { 343 AgentXPending p = (AgentXPending) it.next(); 344 if (p.getSession().getSessionID() == sessionID) { 345 if (remove) { 346 it.remove(); 347 if (requests.isEmpty()) { 348 queue.remove(this); 349 } 350 } 351 return p; 352 } 353 } 354 return null; 355 } 356 357 public synchronized final boolean isEmpty() { 358 return requests.isEmpty(); 359 } 360 361 public synchronized final Collection getPending() { 362 LinkedList pending = new LinkedList (); 363 for (Iterator it = requests.iterator(); it.hasNext(); ) { 364 AgentXPending item = (AgentXPending) it.next(); 365 if (item.isPending()) { 366 pending.add(item); 367 } 368 } 369 return pending; 370 } 371 } 372 } 373 | Popular Tags |