1 22 23 24 package org.snmp4j.agent.agentx.subagent; 25 26 import java.util.*; 27 28 import org.snmp4j.*; 29 import org.snmp4j.mp.*; 30 import org.snmp4j.smi.*; 31 import org.snmp4j.agent.DefaultMOContextScope; 32 import org.snmp4j.agent.MOScope; 33 import org.snmp4j.agent.ManagedObject; 34 import org.snmp4j.log.LogAdapter; 35 import org.snmp4j.log.LogFactory; 36 import org.snmp4j.agent.request.AbstractRequest; 37 import org.snmp4j.agent.request.SubRequest; 38 import org.snmp4j.agent.request.SubRequestIterator; 39 import org.snmp4j.agent.request.RequestStatusListener; 40 import org.snmp4j.agent.request.RequestStatus; 41 import org.snmp4j.agent.request.RequestStatusEvent; 42 import org.snmp4j.agent.agentx.AgentXResponsePDU; 43 import org.snmp4j.agent.agentx.AgentXGetBulkPDU; 44 import org.snmp4j.agent.agentx.AgentXRequestPDU; 45 import org.snmp4j.agent.agentx.AgentXVariableBindingPDU; 46 import org.snmp4j.agent.agentx.AgentXPDU; 47 import org.snmp4j.agent.agentx.AgentXContextPDU; 48 import org.snmp4j.agent.agentx.AgentXCommandEvent; 49 import org.snmp4j.agent.MOQuery; 50 import org.snmp4j.agent.request.SubRequestIteratorSupport; 51 import org.snmp4j.agent.request.Request; 52 53 61 public class AgentXRequest extends AbstractRequest { 62 63 private static final LogAdapter logger = 64 LogFactory.getLogger(AgentXRequest.class); 65 66 public static final OctetString DEFAULT_CONTEXT = new OctetString(); 67 68 private AgentXCommandEvent requestEvent; 69 private AgentXResponsePDU response; 70 71 private static int nextTransactionID = 0; 72 73 public AgentXRequest(AgentXCommandEvent request) { 74 this.requestEvent = request; 75 correctRequestValues(); 76 this.transactionID = nextTransactionID(); 77 } 78 79 public static int nextTransactionID() { 80 return nextTransactionID++; 81 } 82 83 public int size() { 84 if (requestEvent.getCommand() instanceof AgentXRequestPDU) { 85 return ((AgentXRequestPDU)requestEvent.getCommand()).size(); 86 } 87 else if (requestEvent.getCommand() instanceof AgentXVariableBindingPDU) { 88 return ((AgentXVariableBindingPDU)requestEvent.getCommand()).size(); 89 } 90 return 0; 91 } 92 93 public boolean isBulkRequest() { 94 return requestEvent.getCommand().getType() == AgentXPDU.AGENTX_GETBULK_PDU; 95 } 96 97 private void correctRequestValues() { 98 AgentXPDU request = requestEvent.getCommand(); 99 if (request instanceof AgentXGetBulkPDU) { 100 repeaterStartIndex = getNonRepeaters(); 101 repeaterRowSize = 102 Math.max(size() - repeaterStartIndex, 0); 103 } 104 else { 105 repeaterStartIndex = 0; 106 repeaterRowSize = size(); 107 } 108 } 109 110 protected void setupSubRequests() { 111 int capacity = size(); 112 int totalRepetitions = 0; 113 if (requestEvent.getCommand() instanceof AgentXGetBulkPDU) { 114 totalRepetitions = repeaterRowSize * getMaxRepetitions(); 115 } 116 subrequests = new ArrayList(capacity + totalRepetitions); 117 if (response == null) { 118 response = createResponse(); 119 } 120 if (requestEvent.getCommand() instanceof AgentXRequestPDU) { 121 AgentXRequestPDU rangeRequest = 122 (AgentXRequestPDU)requestEvent.getCommand(); 123 MOScope[] ranges = rangeRequest.getRanges(); 124 for (int i = 0; i < ranges.length; i++) { 125 AgentXSubRequest subReq = 126 new AgentXSubRequest( 127 new DefaultMOContextScope(getContext(), ranges[i]), i); 128 addSubRequest(subReq); 129 } 130 } 131 else if (requestEvent.getCommand() instanceof AgentXVariableBindingPDU) { 132 AgentXVariableBindingPDU vbRequest = 133 (AgentXVariableBindingPDU)requestEvent.getCommand(); 134 VariableBinding[] vbs = vbRequest.getVariableBindings(); 135 for (int i = 0; i < vbs.length; i++) { 136 AgentXSubRequest subReq = new AgentXSubRequest(vbs[i], i); 137 addSubRequest(subReq); 138 } 139 } 140 if (logger.isDebugEnabled()) { 141 logger.debug("AgentXSubRequests initialized: "+subrequests); 142 } 143 } 144 145 public int getMaxRepetitions() { 146 if (requestEvent.getCommand() instanceof AgentXGetBulkPDU) { 147 return ((AgentXGetBulkPDU)requestEvent.getCommand()).getMaxRepetitions() 148 & 0xFFFF; 149 } 150 return 0; 151 } 152 153 public int getNonRepeaters() { 154 if (requestEvent.getCommand() instanceof AgentXGetBulkPDU) { 155 return ((AgentXGetBulkPDU)requestEvent.getCommand()).getNonRepeaters() 156 & 0xFFFF; 157 } 158 return 0; 159 } 160 161 private void addSubRequest(SubRequest subReq) { 162 subrequests.add(subReq); 163 response.add(subReq.getVariableBinding()); 164 } 165 166 protected int getMaxPhase() { 167 return (is2PC()) ? PHASE_2PC_CLEANUP : PHASE_1PC; 168 } 169 170 public Object getSource() { 171 return requestEvent; 172 } 173 174 public void setRequestEvent(AgentXCommandEvent requestEvent) { 175 this.requestEvent = requestEvent; 176 } 177 178 protected void assignErrorStatus2Response() { 179 int errStatus = getErrorStatus(); 180 response.setErrorStatus((short)errStatus); 181 response.setErrorIndex((short)getErrorIndex()); 182 } 183 184 private AgentXResponsePDU createResponse() { 185 AgentXResponsePDU resp = 186 new AgentXResponsePDU(0, (short)0, (short)0); 187 resp.setTransactionID(transactionID); 188 return resp; 189 } 190 191 public AgentXResponsePDU getResponsePDU() { 192 return (AgentXResponsePDU) getResponse(); 193 } 194 195 public Object getResponse() { 196 if (response == null) { 197 response = createResponse(); 198 assignErrorStatus2Response(); 199 } 200 else { 201 assignErrorStatus2Response(); 202 } 203 if (is2PC()) { 204 response.clear(); 205 if ((requestEvent.getCommand().getType() == AgentXPDU.AGENTX_CLEANUPSET_PDU) || 206 (requestEvent.getCommand().getType() == AgentXPDU.AGENTX_UNDOSET_PDU)) { 207 return null; 208 } 209 } 210 return response; 211 } 212 213 public Iterator iterator() { 214 initSubRequests(); 215 return new AgentXSubRequestIterator(); 216 } 217 218 219 protected boolean is2PC() { 220 return ((requestEvent.getCommand().getType() >= AgentXPDU.AGENTX_TESTSET_PDU) && 221 (requestEvent.getCommand().getType() <= AgentXPDU.AGENTX_CLEANUPSET_PDU)); 222 } 223 224 public OctetString getContext() { 225 if (requestEvent.getCommand() instanceof AgentXContextPDU) { 226 return ((AgentXContextPDU)requestEvent.getCommand()).getContext(); 227 } 228 return DEFAULT_CONTEXT; 229 } 230 231 public OctetString getViewName() { 232 throw new UnsupportedOperationException (); 233 } 234 235 public void setViewName(OctetString viewName) { 236 throw new UnsupportedOperationException (); 237 } 238 239 public int getSecurityLevel() { 240 throw new UnsupportedOperationException (); 241 } 242 243 public int getSecurityModel() { 244 throw new UnsupportedOperationException (); 245 } 246 247 public OctetString getSecurityName() { 248 throw new UnsupportedOperationException (); 249 } 250 251 public int getViewType() { 252 throw new UnsupportedOperationException (); 253 } 254 255 protected synchronized void addRepeaterSubRequest() { 256 int predecessorIndex = subrequests.size() - repeaterRowSize; 257 AgentXSubRequest sreq = 258 new AgentXSubRequest((AgentXSubRequest)subrequests.get(predecessorIndex), 259 subrequests.size()); 260 addSubRequest(sreq); 261 } 262 263 270 private List lastRow() { 271 if (repeaterRowSize == 0) { 272 return null; 273 } 274 int rows = (subrequests.size() - repeaterStartIndex) / repeaterRowSize; 275 int startIndex = repeaterStartIndex + (repeaterRowSize*(rows-1)); 276 int endIndex = repeaterStartIndex + (repeaterRowSize*rows); 277 return subrequests.subList(startIndex, endIndex); 278 } 279 280 public int getMessageProcessingModel() { 281 throw new UnsupportedOperationException (); 282 } 283 284 public String toString() { 285 return getClass().getName()+"[subrequests="+subrequests+",phase="+phase+ 286 ",requestEvent="+requestEvent+"]"; 287 } 288 289 public boolean isPhaseComplete() { 290 if (errorStatus == SnmpConstants.SNMP_ERROR_SUCCESS) { 291 initSubRequests(); 292 for (Iterator it = subrequests.iterator(); it.hasNext(); ) { 293 SubRequest subreq = (SubRequest) it.next(); 294 RequestStatus status = subreq.getStatus(); 295 if (status.getErrorStatus() != SnmpConstants.SNMP_ERROR_SUCCESS) { 296 return true; 297 } 298 else if (!status.isPhaseComplete()) { 299 return false; 300 } 301 } 302 } 303 return true; 304 } 305 306 315 public class AgentXSubRequestIterator implements SubRequestIterator { 316 317 private int cursor = 0; 318 private int increment = 1; 319 320 protected AgentXSubRequestIterator() { 321 } 322 323 protected AgentXSubRequestIterator(int offset, int increment) { 324 this.cursor = offset; 325 this.increment = increment; 326 } 327 328 private int getRepeaterCount() { 329 AgentXPDU pdu = requestEvent.getCommand(); 330 if (pdu instanceof AgentXGetBulkPDU) { 331 AgentXGetBulkPDU bulkPDU = (AgentXGetBulkPDU)pdu; 332 return Math.max(bulkPDU.size() - bulkPDU.getNonRepeaters(), 0); 333 } 334 return 0; 335 } 336 337 public boolean hasNext() { 338 AgentXPDU reqPDU = requestEvent.getCommand(); 339 if (reqPDU.getType() == AgentXPDU.AGENTX_GETBULK_PDU) { 340 AgentXGetBulkPDU bulkPDU = (AgentXGetBulkPDU)reqPDU; 341 if (cursor < Math.min(bulkPDU.size(), bulkPDU.getNonRepeaters())) { 342 return true; 343 } 344 else { 345 if (cursor < bulkPDU.getNonRepeaters() + 346 bulkPDU.getMaxRepetitions() * getRepeaterCount()) { 347 List lastRow = lastRow(); 348 if (lastRow != null) { 349 boolean allEndOfMibView = true; 350 for (Iterator it = lastRow.iterator(); it.hasNext();) { 351 SubRequest sreq = (SubRequest) it.next(); 352 if (sreq.getVariableBinding().getSyntax() != 353 SMIConstants.EXCEPTION_END_OF_MIB_VIEW) { 354 allEndOfMibView = false; 355 break; 356 } 357 } 358 if (allEndOfMibView) { 359 return false; 360 } 361 } 362 return true; 363 } 364 } 365 return false; 366 } 367 return (cursor < size()); 368 } 369 370 public SubRequest nextSubRequest() { 371 if (!hasNext()) { 372 throw new NoSuchElementException(); 373 } 374 if ((isBulkRequest()) && 375 (cursor >= subrequests.size())) { 376 while (cursor >= subrequests.size()) { 377 addRepeaterSubRequest(); 378 } 379 } 380 SubRequest sreq = (SubRequest) subrequests.get(cursor); 381 cursor += increment; 382 return sreq; 383 } 384 385 public void remove() { 386 throw new UnsupportedOperationException ("Remove is not supported "+ 387 "on sub-requests"); 388 } 389 390 public Object next() { 391 return nextSubRequest(); 392 } 393 394 public boolean equals(Object other) { 395 if (other instanceof AgentXRequest) { 396 return ((AgentXRequest)other).getTransactionID() == getTransactionID(); 397 } 398 return false; 399 } 400 401 public int hashCode() { 402 return getTransactionID(); 403 } 404 } 405 406 407 414 public class AgentXSubRequest implements SubRequest, RequestStatusListener { 415 416 private RequestStatus status; 417 private VariableBinding vb; 418 private Object undoValue; 419 private MOScope scope; 420 private MOQuery query; 421 private ManagedObject targetMO; 422 private int index; 423 424 private volatile Object userObject; 425 426 private AgentXSubRequest(int index) { 427 this.index = index; 428 status = new RequestStatus(); 429 status.addRequestStatusListener(this); 430 } 431 432 protected AgentXSubRequest(MOScope searchRange, int index) { 433 this(index); 434 this.scope = searchRange; 435 this.vb = new VariableBinding(searchRange.getLowerBound()); 436 } 437 438 protected AgentXSubRequest(VariableBinding subrequest, int index) { 439 this(index); 440 this.vb = subrequest; 441 OID oid = this.vb.getOid(); 442 this.scope = new DefaultMOContextScope(getContext(), 443 oid, true, oid, true); 444 } 445 446 protected AgentXSubRequest(AgentXSubRequest predecessor, int index) { 447 this(index); 448 this.vb = new VariableBinding(predecessor.getVariableBinding().getOid()); 449 switch (requestEvent.getCommand().getType()) { 450 case AgentXPDU.AGENTX_GETBULK_PDU: 451 case AgentXPDU.AGENTX_GETNEXT_PDU: { 452 this.scope = 453 new DefaultMOContextScope(getContext(), 454 predecessor.getVariableBinding().getOid(), 455 false, 456 predecessor.getScope().getUpperBound(), 457 predecessor.getScope().isUpperIncluded()); 458 break; 459 } 460 default: { 461 this.scope = new DefaultMOContextScope(getContext(), 462 predecessor.getScope()); 463 } 464 } 465 } 468 469 public Request getRequest() { 470 return AgentXRequest.this; 471 } 472 473 public RequestStatus getStatus() { 474 return status; 475 } 476 477 public VariableBinding getVariableBinding() { 478 return vb; 479 } 480 481 public void setStatus(RequestStatus status) { 482 this.status = status; 483 } 484 485 public Object getUndoValue() { 486 return undoValue; 487 } 488 489 public void setUndoValue(Object undoInformation) { 490 this.undoValue = undoInformation; 491 } 492 493 public void requestStatusChanged(RequestStatusEvent event) { 494 int newStatus = event.getStatus().getErrorStatus(); 495 AgentXRequest.this.setErrorStatus(newStatus); 496 if (logger.isDebugEnabled() && 497 (newStatus != SnmpConstants.SNMP_ERROR_SUCCESS)) { 498 new Exception ("Error "+event.getStatus().getErrorStatus()+ 499 " generated at: "+vb).printStackTrace(); 500 } 501 } 502 503 public MOScope getScope() { 504 return scope; 505 } 506 507 public void completed() { 508 status.setPhaseComplete(true); 509 } 510 511 public boolean hasError() { 512 return getStatus().getErrorStatus() != SnmpConstants.SNMP_ERROR_SUCCESS; 513 } 514 515 public boolean isComplete() { 516 return status.isPhaseComplete(); 517 } 518 519 public void setTargetMO(ManagedObject managedObject) { 520 this.targetMO = managedObject; 521 } 522 523 public ManagedObject getTargetMO() { 524 return targetMO; 525 } 526 527 public int getIndex() { 528 return index; 529 } 530 531 public void setQuery(MOQuery query) { 532 this.query = query; 533 } 534 535 public MOQuery getQuery() { 536 return query; 537 } 538 539 public String toString() { 540 return getClass().getName()+"[scope="+scope+ 541 ",vb="+vb+",status="+status+",query="+query+",index="+index+ 542 ",targetMO="+targetMO+"]"; 543 } 544 545 public SubRequestIterator repetitions() { 546 initSubRequests(); 547 if (requestEvent.getCommand().getType() == AgentXPDU.AGENTX_GETBULK_PDU) { 548 AgentXGetBulkPDU getBulk = (AgentXGetBulkPDU) requestEvent.getCommand(); 549 int repeaters = getBulk.size() - getBulk.getNonRepeaters(); 550 return new AgentXSubRequestIterator(getIndex(), repeaters); 551 } 552 return new SubRequestIteratorSupport(Collections.EMPTY_LIST.iterator()); 553 } 554 555 public void updateNextRepetition() { 556 SubRequestIterator repetitions = repetitions(); 557 repetitions.next(); 559 if (repetitions.hasNext()) { 560 if ((getStatus().getErrorStatus() == PDU.noError) && 561 (!this.vb.isException())) { 562 AgentXSubRequest nsreq = 563 (AgentXSubRequest) repetitions.nextSubRequest(); 564 nsreq.query = null; 565 nsreq.scope = 566 new DefaultMOContextScope(getContext(), 567 this.getVariableBinding().getOid(), 568 false, 569 this.getScope().getUpperBound(), 570 this.getScope().isUpperIncluded()); 571 } 572 else if (this.vb.isException()) { 573 while (repetitions.hasNext()) { 574 AgentXSubRequest nsreq = 575 (AgentXSubRequest) repetitions.nextSubRequest(); 576 nsreq.query = null; 577 nsreq.getVariableBinding().setOid(this.vb.getOid()); 578 nsreq.getVariableBinding().setVariable(this.vb.getVariable()); 579 nsreq.getStatus().setPhaseComplete(true); 580 } 581 } 582 } 583 } 584 585 public final void setErrorStatus(int errorStatus) { 586 getStatus().setErrorStatus(errorStatus); 587 } 588 589 public final int getErrorStatus() { 590 return getStatus().getErrorStatus(); 591 } 592 593 public Object getUserObject() { 594 return userObject; 595 } 596 597 public void setUserObject(Object userObject) { 598 this.userObject = userObject; 599 } 600 } 601 } 602 603 | Popular Tags |