KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > snmp4j > agent > agentx > master > AgentXQueue


1 /*_############################################################################
2   _##
3   _## SNMP4J-AgentX - AgentXQueue.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.master;
25
26 import java.util.Collection JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.LinkedList JavaDoc;
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 JavaDoc queue = new LinkedList JavaDoc();
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       // optimize upper bound if server is set
111
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 JavaDoc 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               // this is a repetitions -> ignore it this time and send out
127
// AgentX request
128
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           // optimize upper bound if server is set
136
if (server != null) {
137             optimizeSearchRange(searchRange, entry);
138           }
139           break;
140         }
141         default: {
142           // do nothing special
143
}
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   /**
214    * Returns the AgentX request in the queue identified by an AgentX session ID
215    * and a transaction ID.
216    * @param sessionID
217    * the session ID.
218    * @param transactionID
219    * the transaction ID.
220    * @return
221    * the associated <code>AgentXPending</code> instance or <code>null</code>
222    * if no such request exists.
223    */

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   /**
234    * Returns the AgentX request in the queue identified by an AgentX session ID
235    * and a transaction ID and removes that request from the queue.
236    *
237    * @param sessionID
238    * the session ID.
239    * @param transactionID
240    * the transaction ID.
241    * @return
242    * the associated <code>AgentXPending</code> instance or <code>null</code>
243    * if no such request exists.
244    */

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   /**
255    * Return all pending AgentX requests for the specified transaction ID.
256    *
257    * @param transactionID
258    * a transcation ID.
259    * @return
260    * a possibly empty List of pending requests.
261    */

262   public synchronized AgentXQueueEntry get(int transactionID) {
263     return getQueueEntry(transactionID, false);
264   }
265
266   /**
267    * Remove all AgentX request entries for the supplied transaction ID.
268    * @param transactionID
269    * a transaction ID.
270    */

271   public synchronized void removeAll(int transactionID) {
272     getQueueEntry(transactionID, true);
273   }
274
275   private AgentXQueueEntry getQueueEntry(int transactionID, boolean remove) {
276     for (Iterator JavaDoc 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 JavaDoc {
289
290     private int transactionID;
291     private LinkedList JavaDoc 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 JavaDoc();
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 JavaDoc 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 JavaDoc toString() {
332       return "AgentXQueueEntry[transactionID="+transactionID+",requests="+
333           requests+"]";
334     }
335
336     public int compareTo(Object JavaDoc 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 JavaDoc 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 JavaDoc getPending() {
362       LinkedList JavaDoc pending = new LinkedList JavaDoc();
363       for (Iterator JavaDoc 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