1 22 23 package org.snmp4j.agent.agentx.master.index; 24 25 import java.util.*; 26 27 import org.snmp4j.agent.agentx.AgentXProtocol; 28 import org.snmp4j.smi.*; 29 import org.snmp4j.agent.agentx.master.index.AgentXIndexRegistry.IndexEntry; 30 import org.snmp4j.agent.agentx.master.index.AgentXIndexRegistry.IndexRegistryEntry; 31 import org.snmp4j.log.LogAdapter; 32 import org.snmp4j.log.LogFactory; 33 34 35 public class AgentXIndexRegistry { 36 37 private static final LogAdapter LOGGER = 38 LogFactory.getLogger(AgentXIndexRegistry.class); 39 40 private Map indexes = Collections.synchronizedMap(new HashMap()); 41 42 public AgentXIndexRegistry() { 43 } 44 45 public int allocate(int sessionID, 46 OctetString context, VariableBinding vb, 47 boolean testOnly) { 48 try { 49 vb.getVariable().toSubIndex(true); 50 } 51 catch (UnsupportedOperationException ex) { 52 return AgentXProtocol.AGENTX_INDEX_WRONG_TYPE; 53 } 54 IndexRegistryEntry newEntry = new IndexRegistryEntry(context, vb); 55 IndexRegistryEntry oldEntry = (IndexRegistryEntry) indexes.get(newEntry); 56 if (oldEntry == null) { 57 if (!testOnly) { 58 int status = newEntry.allocate(sessionID, vb.getVariable(), testOnly); 59 if (status == AgentXProtocol.AGENTX_SUCCESS) { 60 indexes.put(newEntry, newEntry); 61 } 62 return status; 63 } 64 return AgentXProtocol.AGENTX_SUCCESS; 65 } 66 else { 67 return oldEntry.allocate(sessionID, vb.getVariable(), testOnly); 68 } 69 } 70 71 public int release(int sessionID, 72 OctetString context, VariableBinding vb, 73 boolean testOnly) { 74 IndexRegistryEntry newEntry = new IndexRegistryEntry(context, vb); 75 IndexRegistryEntry entry = (IndexRegistryEntry) indexes.get(newEntry); 76 if (entry == null) { 77 return AgentXProtocol.AGENTX_INDEX_NOT_ALLOCATED; 78 } 79 else { 80 if (entry.getIndexType().getSyntax() != vb.getSyntax()) { 81 return AgentXProtocol.AGENTX_INDEX_NOT_ALLOCATED; 82 } 83 return entry.release(sessionID, vb.getVariable(), testOnly); 84 } 85 } 86 87 public void release(int sessionID) { 88 synchronized (indexes) { 89 for (Iterator it = indexes.values().iterator(); it.hasNext(); ) { 90 IndexRegistryEntry entry = (IndexRegistryEntry) it.next(); 91 entry.release(sessionID); 92 } 93 } 94 } 95 96 public int newIndex(int sessionID, 97 OctetString context, VariableBinding vb, 98 boolean testOnly) { 99 IndexRegistryEntry newEntry = new IndexRegistryEntry(context, vb); 100 IndexRegistryEntry entry = (IndexRegistryEntry) indexes.get(newEntry); 101 if (entry == null) { 102 entry = new IndexRegistryEntry(context, vb); 103 } 104 Variable v = entry.newIndex(sessionID, testOnly); 105 if (v == null) { 106 return AgentXProtocol.AGENTX_INDEX_NONE_AVAILABLE; 107 } 108 else if (!testOnly) { 109 vb.setVariable(v); 110 } 111 return AgentXProtocol.AGENTX_SUCCESS; 112 } 113 114 public int anyIndex(int sessionID, 115 OctetString context, VariableBinding vb, 116 boolean testOnly) { 117 IndexRegistryEntry newEntry = new IndexRegistryEntry(context, vb); 118 IndexRegistryEntry entry = (IndexRegistryEntry) indexes.get(newEntry); 119 boolean newEntryCreated = false; 120 if (entry == null) { 121 entry = new IndexRegistryEntry(context, vb); 122 newEntryCreated = true; 123 } 124 Variable v = entry.anyIndex(sessionID, testOnly); 125 if (v == null) { 126 return AgentXProtocol.AGENTX_INDEX_NONE_AVAILABLE; 127 } 128 else if (!testOnly) { 129 vb.setVariable(v); 130 if (newEntryCreated) { 131 indexes.put(entry, entry); 132 } 133 } 134 return AgentXProtocol.AGENTX_SUCCESS; 135 } 136 137 class IndexEntry implements Comparable { 138 private int sessionID; 139 private Variable indexValue; 140 141 public IndexEntry(int sessionID, Variable indexValue) { 142 this.sessionID = sessionID; 143 this.indexValue = indexValue; 144 } 145 146 public int getSessionID() { 147 return sessionID; 148 } 149 150 public Variable getIndexValue() { 151 return indexValue; 152 } 153 154 public int hashCode() { 155 return indexValue.hashCode(); 156 } 157 158 public boolean equals(Object o) { 159 if (o instanceof IndexEntry) { 160 return ((indexValue.equals(((IndexEntry)o).indexValue)) && 161 (sessionID == ((IndexEntry)o).sessionID)); 162 } 163 else if (o instanceof Variable) { 164 return indexValue.equals(o); 165 } 166 return false; 167 } 168 169 public int compareTo(Object o) { 170 OID indexOID = indexValue.toSubIndex(true); 171 if (o instanceof IndexEntry) { 172 return indexOID.compareTo(((IndexEntry)o).indexValue.toSubIndex(true)); 173 } 174 else if (o instanceof Variable) { 175 return indexOID.compareTo(((Variable)o).toSubIndex(true)); 176 } 177 throw new ClassCastException (o.getClass()+" != (IndexEntry or Variable)"); 178 } 179 } 180 181 class IndexRegistryEntry implements Comparable { 182 183 private OctetString context; 184 private VariableBinding indexType; 185 private SortedMap indexValues = new TreeMap(new IndexComparator()); 186 private SortedMap usedValues = new TreeMap(new IndexComparator()); 187 188 public IndexRegistryEntry(OctetString context, VariableBinding indexType) { 189 this.context = (context == null) ? new OctetString() : context; 190 this.indexType = indexType; 191 } 192 193 public synchronized int allocate(int sessionID, 194 Variable indexValue, boolean testOnly) { 195 if (indexValue.getSyntax() != indexType.getSyntax()) { 196 return AgentXProtocol.AGENTX_INDEX_WRONG_TYPE; 197 } 198 else if (indexValues.get(indexValue) != null) { 199 return AgentXProtocol.AGENTX_INDEX_ALREADY_ALLOCATED; 200 } 201 else { 202 if (!testOnly) { 203 IndexEntry newEntry = new IndexEntry(sessionID, indexValue); 204 indexValues.put(newEntry, newEntry); 205 } 206 return AgentXProtocol.AGENTX_SUCCESS; 207 } 208 } 209 210 public synchronized int release(int sessionID, 211 Variable indexValue, boolean testOnly) { 212 IndexEntry removeKey = new IndexEntry(sessionID, indexValue); 213 IndexEntry contained = (IndexEntry) indexValues.get(removeKey); 214 if ((contained != null) && (contained.getSessionID() == sessionID)) { 215 if (!testOnly) { 216 Object r = indexValues.remove(contained); 217 usedValues.put(r,r); 218 } 219 return AgentXProtocol.AGENTX_SUCCESS; 220 } 221 return AgentXProtocol.AGENTX_INDEX_NOT_ALLOCATED; 222 } 223 224 public synchronized void release(int sessionID) { 225 for (Iterator it = indexValues.values().iterator(); it.hasNext();) { 226 IndexEntry entry = (IndexEntry) it.next(); 227 if (entry.getSessionID() == sessionID) { 228 it.remove(); 229 usedValues.put(entry, entry); 230 } 231 } 232 } 233 234 public int compareTo(Object o) { 235 IndexRegistryEntry other = (IndexRegistryEntry)o; 236 int c = context.compareTo(other.context); 237 if (c == 0) { 238 c = indexType.getOid().compareTo(other.indexType.getOid()); 239 } 240 return c; 241 } 242 243 public int hashCode() { 244 return indexType.getOid().hashCode(); 245 } 246 247 public boolean equals(Object o) { 248 if (o instanceof IndexRegistryEntry) { 249 return indexType.getOid().equals( 250 ((IndexRegistryEntry)o).indexType.getOid()); 251 } 252 return false; 253 } 254 255 public VariableBinding getIndexType() { 256 return indexType; 257 } 258 259 public OctetString getContext() { 260 return context; 261 } 262 263 public synchronized Variable newIndex(int sessionID, boolean testOnly) { 264 try { 265 IndexEntry last = null; 266 if (!usedValues.isEmpty()) { 267 last = (IndexEntry) usedValues.lastKey(); 268 } 269 if (!indexValues.isEmpty()) { 270 IndexEntry lastAllocated = (IndexEntry) indexValues.lastKey(); 271 if (last == null) { 272 last = lastAllocated; 273 } 274 else if (lastAllocated.compareTo(last) > 0) { 275 last = lastAllocated; 276 } 277 } 278 else if (last == null) { 279 return anyIndex(sessionID, testOnly); 280 } 281 OID nextIndex = last.getIndexValue().toSubIndex(true); 282 nextIndex = nextIndex.nextPeer(); 283 Variable nextIndexValue = (Variable)last.getIndexValue().clone(); 284 nextIndexValue.fromSubIndex(nextIndex, true); 285 int status = allocate(sessionID, nextIndexValue, testOnly); 286 if (status != AgentXProtocol.AGENTX_SUCCESS) { 287 return null; 288 } 289 return nextIndexValue; 290 } 291 catch (Exception ex) { 292 LOGGER.error("Exception occurred while creating/allocating new index:"+ 293 ex.getMessage(), ex); 294 return null; 295 } 296 } 297 298 public synchronized Variable anyIndex(int sessionID, boolean testOnly) { 299 try { 300 OID nextIndex; 301 if (usedValues.isEmpty()) { 302 if (indexValues.isEmpty()) { 303 nextIndex = indexType.getVariable().toSubIndex(true); 304 } 305 else { 306 nextIndex = ((IndexEntry)indexValues.lastKey()). 307 getIndexValue().toSubIndex(true); 308 } 309 } 310 else { 311 IndexEntry last = (IndexEntry) usedValues.firstKey(); 312 nextIndex = last.getIndexValue().toSubIndex(true); 313 } 314 nextIndex = nextIndex.nextPeer(); 315 Variable nextIndexValue = (Variable) indexType.getVariable().clone(); 316 nextIndexValue.fromSubIndex(nextIndex, true); 317 int status = allocate(sessionID, nextIndexValue, testOnly); 318 if (status != AgentXProtocol.AGENTX_SUCCESS) { 319 return null; 320 } 321 return nextIndexValue; 322 } 323 catch (Exception ex) { 324 LOGGER.error("Exception occurred while creating/allocating"+ 325 " any new index:"+ex.getMessage(), ex); 326 return null; 327 } 328 } 329 330 private class IndexComparator implements Comparator { 331 332 public int compare(Object o1, Object o2) { 333 Variable c1,c2; 334 if (o1 instanceof IndexEntry) { 335 c1 = ((IndexEntry)o1).getIndexValue(); 336 } 337 else { 338 c1 = (Variable)o1; 339 } 340 if (o2 instanceof IndexEntry) { 341 c2 = ((IndexEntry)o2).getIndexValue(); 342 } 343 else { 344 c2 = (Variable)o2; 345 } 346 return c1.compareTo(c2); 347 } 348 349 } 350 } 351 } 352 | Popular Tags |