KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snmp4j > agent > agentx > subagent > AgentXRequest


1 /*_############################################################################
2   _##
3   _## SNMP4J-AgentX - AgentXRequest.java
4   _##
5   _## Copyright (C) 2005-2007 Frank Fock (SNMP4J.org)
6   _##
7   _## This program is free software; you can redistribute it and/or modify
8   _## it under the terms of the GNU General Public License version 2 as
9   _## published by the Free Software Foundation.
10   _##
11   _## This program is distributed in the hope that it will be useful,
12   _## but WITHOUT ANY WARRANTY; without even the implied warranty of
13   _## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14   _## GNU General Public License for more details.
15   _##
16   _## You should have received a copy of the GNU General Public License
17   _## along with this program; if not, write to the Free Software
18   _## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19   _## MA 02110-1301 USA
20   _##
21   _##########################################################################*/

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 /**
54  * The <code>AgentXRequest</code> class represents AgentX sub-agent requests.
55  * AgentX sub-agent requests are similar to SNMP requests but especially for
56  * SET request processing and query scopes differences apply.
57  *
58  * @author Frank Fock
59  * @version 1.0
60  */

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 JavaDoc 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 JavaDoc 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 JavaDoc();
233   }
234
235   public void setViewName(OctetString viewName) {
236     throw new UnsupportedOperationException JavaDoc();
237   }
238
239   public int getSecurityLevel() {
240     throw new UnsupportedOperationException JavaDoc();
241   }
242
243   public int getSecurityModel() {
244     throw new UnsupportedOperationException JavaDoc();
245   }
246
247   public OctetString getSecurityName() {
248     throw new UnsupportedOperationException JavaDoc();
249   }
250
251   public int getViewType() {
252     throw new UnsupportedOperationException JavaDoc();
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   /**
264    * Returns the last repetition row that is complete (regarding the number
265    * of elements in the row).
266    * @return
267    * a sub list of the sub-requests list that contains the row's elements.
268    * If no such row exists <code>null</code> is returned.
269    */

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 JavaDoc();
282   }
283
284   public String JavaDoc 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   /**
307    * The AgentXSubRequestIterator iterates over the subrequests in a AgentX
308    * request. In case of bulk operations, it also may physically append
309    * new sub-request instances while iterating, until the bulk operations
310    * limits are reached.
311    *
312    * @author Frank Fock
313    * @version 1.0
314    */

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 JavaDoc("Remove is not supported "+
387                                               "on sub-requests");
388     }
389
390     public Object JavaDoc next() {
391       return nextSubRequest();
392     }
393
394     public boolean equals(Object JavaDoc 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   /**
408    * The <code>AgentXSubRequest</code> implements the <code>SubRequest</code>
409    * interface for AgentX sub-requests.
410    *
411    * @author Frank Fock
412    * @version 1.0
413    */

414   public class AgentXSubRequest implements SubRequest, RequestStatusListener {
415
416     private RequestStatus status;
417     private VariableBinding vb;
418     private Object JavaDoc undoValue;
419     private MOScope scope;
420     private MOQuery query;
421     private ManagedObject targetMO;
422     private int index;
423
424     private volatile Object JavaDoc 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 // Do not copy queries because they need to be updated externally only!
466
// this.query = predecessor.getQuery();
467
}
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 JavaDoc getUndoValue() {
486       return undoValue;
487     }
488
489     public void setUndoValue(Object JavaDoc 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 JavaDoc("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 JavaDoc 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       // skip this one
558
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 JavaDoc getUserObject() {
594       return userObject;
595     }
596
597     public void setUserObject(Object JavaDoc userObject) {
598       this.userObject = userObject;
599     }
600   }
601 }
602
603
Popular Tags