1 20 package org.jboss.jmx.adaptor.snmp.agent; 21 22 import java.io.InputStream ; 23 import java.util.ArrayList ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 import java.util.regex.Matcher ; 27 import java.util.regex.Pattern ; 28 import java.util.regex.PatternSyntaxException ; 29 30 import javax.management.Notification ; 31 32 import org.jboss.jmx.adaptor.snmp.config.notification.Mapping; 33 import org.jboss.jmx.adaptor.snmp.config.notification.VarBind; 34 import org.jboss.jmx.adaptor.snmp.config.notification.VarBindList; 35 import org.jboss.logging.Logger; 36 import org.jboss.xb.binding.GenericObjectModelFactory; 37 import org.jboss.xb.binding.ObjectModelFactory; 38 import org.jboss.xb.binding.Unmarshaller; 39 import org.jboss.xb.binding.UnmarshallerFactory; 40 import org.jboss.xb.binding.UnmarshallingContext; 41 import org.opennms.protocols.snmp.SnmpPduPacket; 42 import org.opennms.protocols.snmp.SnmpPduRequest; 43 import org.opennms.protocols.snmp.SnmpPduTrap; 44 import org.xml.sax.Attributes ; 45 46 83 public class TrapFactorySupport 84 implements TrapFactory 85 { 86 87 private static final Logger log = Logger.getLogger(TrapFactorySupport.class); 88 89 90 private SnmpVarBindFactory snmpVBFactory = null; 91 92 93 private String notificationMapResName = null; 94 95 96 private Clock clock = null; 97 98 99 private Counter trapCount = null; 100 101 102 private ArrayList notificationMapList = null; 103 104 105 private ArrayList mappingRegExpCache = null; 106 107 108 private ArrayList notificationWrapperCache = null; 109 110 113 public TrapFactorySupport() 114 { 115 this.snmpVBFactory = new SnmpVarBindFactory(); 116 } 117 118 122 public void set(String notificationMapResName, Clock clock, Counter count) 123 { 124 this.notificationMapResName = notificationMapResName; 125 this.clock = clock; 126 this.trapCount = count; 127 } 128 129 138 public void start() 139 throws Exception 140 { 141 log.debug("Reading resource: '" + notificationMapResName + "'"); 142 143 ObjectModelFactory omf = new NotificationBinding(); 144 InputStream is = null; 145 try 146 { 147 is = this.getClass().getResourceAsStream(notificationMapResName); 149 150 Unmarshaller unmarshaller = UnmarshallerFactory.newInstance().newUnmarshaller(); 152 153 this.notificationMapList = (ArrayList )unmarshaller.unmarshal(is, omf, null); 155 } 156 catch (Exception e) 157 { 158 log.error("Accessing resource '" + notificationMapResName + "'"); 159 throw e; 160 } 161 finally 162 { 163 if (is != null) 164 { 165 is.close(); 167 } 168 } 169 log.debug("Found " + notificationMapList.size() + " notification mappings"); 170 171 this.mappingRegExpCache = 174 new ArrayList (notificationMapList.size()); 175 176 this.notificationWrapperCache = 178 new ArrayList (notificationMapList.size()); 179 180 for (Iterator i = notificationMapList.iterator(); i.hasNext(); ) 181 { 182 Mapping mapping = (Mapping)i.next(); 183 184 String notificationType = mapping.getNotificationType(); 186 187 try 188 { 189 Pattern re = Pattern.compile(notificationType); 190 this.mappingRegExpCache.add(re); 191 } 192 catch (PatternSyntaxException e) 193 { 194 this.mappingRegExpCache.add(null); 196 197 log.warn("Error compiling notification mapping for type: " + notificationType, e); 198 } 199 200 String wrapperClassName = mapping.getVarBindList().getWrapperClass(); 203 204 log.debug("notification wrapper class: " + wrapperClassName); 205 206 try 207 { 208 NotificationWrapper wrapper = 209 (NotificationWrapper)Class.forName(wrapperClassName, true, this.getClass().getClassLoader()).newInstance(); 210 211 wrapper.set(this.clock, this.trapCount); 213 214 this.notificationWrapperCache.add(wrapper); 216 } 217 catch (Exception e) 218 { 219 this.notificationWrapperCache.add(null); 221 222 log.warn("Error compiling notification mapping for type: " + notificationType, e); 223 } 224 } 225 log.debug("Trap factory going active"); 226 } 227 228 236 private int findMappingIndex(Notification n) 237 throws IndexOutOfBoundsException 238 { 239 for (int i = 0; i < notificationMapList.size(); i++) 243 { 244 Pattern p = (Pattern ) this.mappingRegExpCache.get(i); 245 246 if (p != null) 247 { 248 Matcher m = p.matcher(n.getType()); 249 250 if (m.matches()) 251 { 252 if (log.isTraceEnabled()) 253 log.trace("Match for '" + n.getType() + "' on mapping " + i); 254 return i; 255 } 256 } 257 } 258 throw new IndexOutOfBoundsException (); 260 } 261 262 265 public SnmpPduTrap generateV1Trap(Notification n) 266 throws MappingFailedException 267 { 268 if (log.isTraceEnabled()) 269 log.trace("generateV1Trap"); 270 271 int index = -1; 273 274 try 275 { 276 index = findMappingIndex(n); 277 } 278 catch (IndexOutOfBoundsException e) 279 { 280 throw new MappingFailedException("No mapping found for notification type: '" + 281 n.getType() + "'"); 282 } 283 284 Mapping m = (Mapping)this.notificationMapList.get(index); 285 286 SnmpPduTrap trapPdu = new SnmpPduTrap(); 288 289 trapPdu.setTimeStamp(this.clock.uptime()); 290 291 trapPdu.setGeneric(m.getGeneric()); 293 trapPdu.setSpecific(m.getSpecific()); 294 trapPdu.setEnterprise(m.getEnterprise()); 295 296 300 NotificationWrapper wrapper = 302 (NotificationWrapper)this.notificationWrapperCache.get(index); 303 304 if(wrapper != null) 305 { 306 wrapper.prime(n); 308 309 List vbList = m.getVarBindList().getVarBindList(); 312 313 for (int i = 0; i < vbList.size(); i++) 314 { 315 VarBind vb = (VarBind)vbList.get(i); 316 317 trapPdu.addVarBind( 323 this.snmpVBFactory.make(vb.getOid(), wrapper.get(vb.getTag()))); 324 } 325 } 326 else 327 { 328 throw new MappingFailedException( 329 "Varbind mapping failure: null wrapper defined for " + 330 " notification type '" + m.getNotificationType() + "'" ); 331 } 332 return trapPdu; 333 } 334 335 340 public SnmpPduPacket generateV2Trap(Notification n) 341 throws MappingFailedException 342 { 343 if (log.isTraceEnabled()) 344 log.trace("generateV2Trap"); 345 346 int index = -1; 348 349 try 350 { 351 index = findMappingIndex(n); 352 } 353 catch (IndexOutOfBoundsException e) 354 { 355 throw new MappingFailedException( 356 "No mapping found for notification type: '" + n.getType() + "'"); 357 } 358 359 Mapping m = (Mapping)this.notificationMapList.get(index); 360 361 SnmpPduRequest trapPdu = new SnmpPduRequest(SnmpPduPacket.V2TRAP); 363 364 368 NotificationWrapper wrapper = 370 (NotificationWrapper)this.notificationWrapperCache.get(index); 371 372 if (wrapper != null) 373 { 374 wrapper.prime(n); 376 377 List vbList = m.getVarBindList().getVarBindList(); 378 379 for (int i = 0; i < vbList.size(); i++) 380 { 381 VarBind vb = (VarBind)vbList.get(i); 382 383 trapPdu.addVarBind( 389 this.snmpVBFactory.make(vb.getOid(), wrapper.get(vb.getTag()))); 390 } 391 } 392 else 393 { 394 log.warn("Varbind mapping failure: null wrapper defined for " + 395 " notification type '" + m.getNotificationType() + "'" ); 396 } 397 return trapPdu; 398 } 399 400 403 private static class NotificationBinding implements GenericObjectModelFactory 404 { 405 407 public Object completeRoot(Object root, UnmarshallingContext ctx, 408 String uri, String name) 409 { 410 return root; 411 } 412 413 public Object newRoot(Object root, UnmarshallingContext navigator, String namespaceURI, 414 String localName, Attributes attrs) 415 { 416 ArrayList notifList; 417 418 if (root == null) 419 { 420 root = notifList = new ArrayList (); 421 } 422 else 423 { 424 notifList = (ArrayList ) root; 425 } 426 return root; 427 } 428 429 public Object newChild(Object parent, UnmarshallingContext navigator, String namespaceURI, 430 String localName, Attributes attrs) 431 { 432 Object child = null; 433 434 if ("mapping".equals(localName)) 435 { 436 Mapping m = new Mapping(); 437 child = m; 438 } 439 else if ("var-bind-list".equals(localName)) 440 { 441 VarBindList vblist = new VarBindList(); 442 child = vblist; 443 if (attrs.getLength() > 0) 444 { 445 for (int i = 0; i < attrs.getLength(); i++) 446 { 447 if ("wrapper-class".equals(attrs.getLocalName(i))) 448 { 449 vblist.setWrapperClass(attrs.getValue(i)); 450 } 451 } 452 } 453 if (vblist.getWrapperClass() == null) 455 { 456 throw new RuntimeException ("'wrapper-class' must be set at 'var-bind-list' element"); 457 } 458 } 459 else if ("var-bind".equals(localName)) 460 { 461 VarBind vb = new VarBind(); 462 child = vb; 463 } 464 return child; 465 } 466 467 public void addChild(Object parent, Object child, UnmarshallingContext navigator, 468 String namespaceURI, String localName) 469 { 470 if (parent instanceof ArrayList ) 471 { 472 ArrayList notifList = (ArrayList )parent; 473 474 if (child instanceof Mapping) 475 { 476 notifList.add(child); 477 } 478 } 479 else if (parent instanceof Mapping) 480 { 481 Mapping m = (Mapping)parent; 482 483 if (child instanceof VarBindList) 484 { 485 m.setVarBindList((VarBindList)child); 486 } 487 } 488 else if (parent instanceof VarBindList) 489 { 490 VarBindList vblist = (VarBindList)parent; 491 492 if (child instanceof VarBind) 493 { 494 vblist.addVarBind((VarBind)child); 495 } 496 } 497 } 498 499 public void setValue(Object o, UnmarshallingContext navigator, String namespaceURI, 500 String localName, String value) 501 { 502 if (o instanceof Mapping) 503 { 504 Mapping m = (Mapping)o; 505 506 if ("notification-type".equals(localName)) 507 { 508 m.setNotificationType(value); 509 } 510 else if ("generic".equals(localName)) 511 { 512 m.setGeneric(Integer.parseInt(value)); 513 } 514 else if ("specific".equals(localName)) 515 { 516 m.setSpecific(Integer.parseInt(value)); 517 } 518 else if ("enterprise".equals(localName)) 519 { 520 m.setEnterprise(value); 521 } 522 } 523 else if (o instanceof VarBind) 524 { 525 VarBind vb = (VarBind)o; 526 527 if ("tag".equals(localName)) 528 { 529 vb.setTag(value); 530 } 531 else if ("oid".equals(localName)) 532 { 533 vb.setOid(value); 534 } 535 } 536 } 537 538 public Object completedRoot(Object root, UnmarshallingContext navigator, String namespaceURI, String localName) 539 { 540 return root; 541 } 542 } 543 544 } | Popular Tags |