1 22 package org.jboss.jmx.adaptor.snmp.agent; 23 24 import java.io.InputStream ; 25 import java.net.InetAddress ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import java.util.SortedMap ; 29 import java.util.SortedSet ; 30 import java.util.TreeMap ; 31 import java.util.TreeSet ; 32 33 import javax.management.Attribute ; 34 import javax.management.MBeanServer ; 35 import javax.management.ObjectName ; 36 37 import org.jboss.jmx.adaptor.snmp.config.attribute.AttributeMappings; 38 import org.jboss.jmx.adaptor.snmp.config.attribute.ManagedBean; 39 import org.jboss.jmx.adaptor.snmp.config.attribute.MappedAttribute; 40 import org.jboss.logging.Logger; 41 import org.jboss.xb.binding.ObjectModelFactory; 42 import org.jboss.xb.binding.Unmarshaller; 43 import org.jboss.xb.binding.UnmarshallerFactory; 44 import org.opennms.protocols.snmp.SnmpAgentSession; 45 import org.opennms.protocols.snmp.SnmpInt32; 46 import org.opennms.protocols.snmp.SnmpNull; 47 import org.opennms.protocols.snmp.SnmpObjectId; 48 import org.opennms.protocols.snmp.SnmpOctetString; 49 import org.opennms.protocols.snmp.SnmpPduPacket; 50 import org.opennms.protocols.snmp.SnmpPduRequest; 51 import org.opennms.protocols.snmp.SnmpSyntax; 52 import org.opennms.protocols.snmp.SnmpUInt32; 53 import org.opennms.protocols.snmp.SnmpVarBind; 54 55 63 public class RequestHandlerImpl extends RequestHandlerSupport 64 implements Reconfigurable 65 { 66 68 private static final String NO_ENTRY_FOUND_FOR_OID = "No entry found for oid "; 69 private static final String SKIP_ENTRY = " - skipping entry"; 70 71 72 73 protected SortedMap bindings = new TreeMap (); 74 75 private SortedSet oidKeys = null; 76 77 78 private boolean initialized = false; 79 80 82 85 public RequestHandlerImpl() 86 { 87 bindings = new TreeMap (); 88 oidKeys = new TreeSet (); 89 } 90 91 93 101 public void initialize(String resourceName, MBeanServer server, Logger log, Clock uptime) 102 throws Exception 103 { 104 log.debug("initialize() with res=" + resourceName); 105 super.initialize(resourceName, server, log, uptime); 106 if (resourceName != null) 107 initializeBindings(); 108 else 109 log.warn("No RequestHandlerResName configured, disabling snmp-get"); 110 111 initialized = true; 112 } 113 114 118 public void reconfigure(String resName) throws Exception 119 { 120 if (resName == null || resName.equals("")) 121 throw new IllegalArgumentException ("Null or empty resName, cannot reconfigure"); 122 123 if (initialized == false) 124 throw new IllegalStateException ("Cannot reconfigure, not initialized yet"); 125 126 this.resourceName = resName; 127 128 bindings.clear(); 130 131 initializeBindings(); 133 } 134 135 137 153 public SnmpPduRequest snmpReceivedGet(SnmpPduPacket pdu, boolean getNext) 154 { 155 try 156 { 157 SnmpPduRequest response = null; 158 int pduLength = pdu.getLength(); 159 final boolean trace = log.isTraceEnabled(); 160 161 if (trace) 162 log.trace("requestId=" + pdu.getRequestId() + ", pduLength=" 163 + pduLength + ", getNext=" + getNext); 164 165 SnmpVarBind[] vblist = new SnmpVarBind[pduLength]; 166 int errorStatus = SnmpPduPacket.ErrNoError; 167 int errorIndex = 0; 168 169 for (int i = 0; i < pduLength; i++) 171 { 172 boolean good = true; 173 SnmpVarBind vb = pdu.getVarBindAt(i); 174 SnmpObjectId oid = vb.getName(); 175 if (getNext) 176 { 177 183 ComparableSnmpObjectId coid = new ComparableSnmpObjectId(oid); 184 oid = getNextOid(coid, true); 185 if (oid == null) 186 { 187 good = false; 188 } 189 else 190 { 191 pdu.setVarBindAt(i, new SnmpVarBind(oid)); 192 } 193 } 194 if (oid!=null) 195 vblist[i] = new SnmpVarBind(oid); 196 else 197 vblist[i] = new SnmpVarBind(vb.getName()); 199 200 if (trace) 201 log.trace("oid=" + oid); 202 203 SnmpSyntax result = null; 204 if (good && bindings != null) 205 result = getValueFor(oid); 206 207 if (trace) 208 log.trace("got result of " + result); 209 210 if (result == null || !good) 211 { 212 errorStatus = SnmpPduPacket.ErrNoSuchName; 213 errorIndex = i + 1; 214 log.debug("Error Occured " + vb.getName().toString()); 215 } 216 else 217 { 218 vblist[i].setValue(result); 219 log.debug("Varbind[" + i + "] := " 220 + vblist[i].getName().toString()); 221 log.debug(" --> " + vblist[i].getValue().toString()); 222 } 223 } response = new SnmpPduRequest(SnmpPduPacket.RESPONSE, vblist); 225 response.setErrorStatus(errorStatus); 226 response.setErrorIndex(errorIndex); 227 return response; 228 } catch (Exception e) 229 { 230 e.printStackTrace(); 232 return null; 233 } 234 } 235 236 249 public SnmpPduRequest snmpReceivedSet(SnmpPduPacket pdu) 250 { 251 final boolean trace = log.isTraceEnabled(); 252 SnmpPduRequest response = null; 253 int errorStatus = SnmpPduPacket.ErrNoError; 254 int errorIndex = 0; 255 int k = pdu.getLength(); 256 SnmpVarBind[] vblist = new SnmpVarBind[k]; 257 258 for (int i = 0; i < k; i++) 259 { 260 SnmpVarBind vb = pdu.getVarBindAt(i); 261 vblist[i] = new SnmpVarBind(vb); 262 SnmpObjectId oid = vb.getName(); 263 SnmpSyntax newVal = vb.getValue(); 264 if (trace) 265 log.trace("set: received oid " + oid.toString() + " with value " + newVal.toString()); 266 SnmpSyntax result = null; 267 try 268 { 269 result = setValueFor(oid,newVal); 270 } 271 catch (ReadOnlyException e) 272 { 273 errorStatus = SnmpPduPacket.ErrReadOnly; 274 errorIndex = i + 1; 275 } 276 277 if (result != null) 278 { 279 errorStatus = SnmpPduPacket.ErrReadOnly; 280 errorIndex = i + 1; 281 log.debug("Error occured " + vb.getName().toString()); 282 } 283 284 if (trace) 285 { 286 log.trace("Varbind[" + i + "] := " + vb.getName().toString()); 287 log.trace(" --> " + vb.getValue().toString()); 288 } 289 } 290 response = new SnmpPduRequest(SnmpPduPacket.RESPONSE, vblist); 291 response.setErrorStatus(errorStatus); 292 response.setErrorIndex(errorIndex); 293 294 return response; 295 } 296 297 316 public void snmpReceivedPdu(SnmpAgentSession session, InetAddress manager, 317 int port, SnmpOctetString community, SnmpPduPacket pdu) 318 { 319 log.error("Message from manager " + manager.toString() + " on port " + port); 320 int cmd = pdu.getCommand(); 321 log.error("Unsupported PDU command......... " + cmd); 322 } 323 324 348 public void SnmpAgentSessionError(SnmpAgentSession session, int error, Object ref) 349 { 350 log.error("An error occured in the trap session"); 351 log.error("Session error code = " + error); 352 if (ref != null) 353 { 354 log.error("Session error reference: " + ref.toString()); 355 } 356 357 if (error == SnmpAgentSession.ERROR_EXCEPTION) 358 { 359 synchronized (session) 360 { 361 session.notify(); } 363 } 364 } 365 366 368 371 private void initializeBindings() throws Exception 372 { 373 log.debug("Reading resource: '" + resourceName + "'"); 374 375 ObjectModelFactory omf = new AttributeMappingsBinding(); 376 InputStream is = null; 377 AttributeMappings mappings = null; 378 try 379 { 380 is = getClass().getResourceAsStream(resourceName); 382 383 Unmarshaller unmarshaller = UnmarshallerFactory.newInstance().newUnmarshaller(); 385 386 mappings = (AttributeMappings)unmarshaller.unmarshal(is, omf, null); 388 } 389 catch (Exception e) 390 { 391 log.error("Accessing resource '" + resourceName + "'"); 392 throw e; 393 } 394 finally 395 { 396 if (is != null) 397 { 398 is.close(); 400 } 401 } 402 if (mappings == null) 403 { 404 log.warn("No bindings found in " + resourceName); 405 return; 406 } 407 log.debug("Found " + mappings.size() + " attribute mappings"); 408 411 412 Iterator it = mappings.iterator(); 413 while (it.hasNext()) 414 { 415 ManagedBean mmb = (ManagedBean)it.next(); 416 String oidPrefix = mmb.getOidPrefix(); 417 List attrs = mmb.getAttributes(); 418 Iterator aIt = attrs.iterator(); 419 while (aIt.hasNext()) 420 { 421 MappedAttribute ma = (MappedAttribute)aIt.next(); 422 String oid; 423 if (oidPrefix != null) 424 oid = oidPrefix + ma.getOid(); 425 else 426 oid = ma.getOid(); 427 428 BindEntry be = new BindEntry(oid, mmb.getName(), ma.getName()); 429 be.isReadWrite = ma.isReadWrite(); 430 431 ComparableSnmpObjectId coid = new ComparableSnmpObjectId(oid); 432 433 if (log.isTraceEnabled()) 434 log.trace("New bind entry " + be); 435 if (bindings.containsKey(coid)) { 436 log.info("Duplicate oid " + oid + SKIP_ENTRY); 437 continue; 438 } 439 if (mmb.getName() == null || mmb.getName().equals("")) 440 { 441 log.info("Invalid mbean name for oid " + oid + SKIP_ENTRY); 442 continue; 443 } 444 if (ma.getName() == null || ma.getName().equals("")) 445 { 446 log.info("Invalid attribute name " + ma.getName() + " for oid " + oid + SKIP_ENTRY); 447 continue; 448 } 449 bindings.put(coid, be); 450 oidKeys.add(coid); 451 452 } 453 } 454 } 455 456 463 private SnmpSyntax getValueFor(final SnmpObjectId oid) { 464 465 BindEntry be = findBindEntryForOid(oid); 466 SnmpSyntax ssy = null; 467 if (be != null) 468 { 469 if (log.isTraceEnabled()) 470 log.trace("Found entry " + be.toString() + " for oid " + oid); 471 472 try 473 { 474 Object val = server.getAttribute(be.mbean, be.attr.getName()); 475 476 if (val instanceof Long ) 477 { 478 Long uin = (Long ) val; 479 ssy = new SnmpUInt32(uin); 480 } 481 else if (val instanceof String ) 482 { 483 String in = (String ) val; 484 ssy = new SnmpOctetString(in.getBytes()); 485 } 486 else if (val instanceof Integer ) 487 { 488 Integer in = (Integer ) val; 489 ssy = new SnmpInt32(in); 490 } 491 else if (val instanceof SnmpObjectId) 492 { 493 ssy = (SnmpObjectId)val; 494 } 495 else 496 log.info("Unknown type for " + be); 497 } 498 catch (Exception e) 499 { 500 log.warn("getValueFor (" + be.mbean.toString() + ", " 501 + be.attr.getName() + ": " + e.toString()); 502 } 503 } 504 else 505 { 506 ssy = new SnmpNull(); 507 log.info(NO_ENTRY_FOUND_FOR_OID + oid); 508 } 509 return ssy; 510 } 511 512 519 private SnmpSyntax setValueFor(final SnmpObjectId oid, final SnmpSyntax newVal) throws ReadOnlyException 520 { 521 final boolean trace = log.isTraceEnabled(); 522 523 BindEntry be = findBindEntryForOid(oid); 524 525 if (trace) 526 log.trace("setValueFor: found bind entry for " + oid); 527 528 SnmpSyntax ssy = null; 529 if (be != null) 530 { 531 if (trace) 532 log.trace("setValueFor: " + be.toString()); 533 534 if (be.isReadWrite == false) 535 { 536 if (trace) 537 log.trace("setValueFor: this is marked read only"); 538 539 throw new ReadOnlyException(oid); 540 } 541 try 542 { 543 Object val = null; 544 if (newVal instanceof SnmpOctetString) 545 { 546 val = newVal.toString(); 547 } 548 else if (newVal instanceof SnmpInt32) 549 { 550 val = new Integer (((SnmpInt32)newVal).getValue()); 551 } 552 else if (newVal instanceof SnmpUInt32) 553 { 554 val = new Long (((SnmpUInt32)newVal).getValue()); 555 } 556 558 if (val != null) 559 { 560 Attribute at = new Attribute (be.attr.getName(), val); 561 server.setAttribute(be.mbean, at); 562 if (trace) 563 log.trace("setValueFor: set attribute in mbean-Server"); 564 } 565 else 566 { 567 log.debug("Did not find a suitable data type for newVal " + newVal); 568 ssy = new SnmpNull(); 569 } 570 } 572 catch (Exception e ) 573 { 574 log.debug("setValueFor: exception " + e.getMessage()); 575 ssy = new SnmpNull(); 576 } 577 } 578 else 579 { 580 ssy = new SnmpNull(); 581 log.info(NO_ENTRY_FOUND_FOR_OID + oid); 582 } 583 return ssy; 584 } 585 586 587 593 private BindEntry findBindEntryForOid(final SnmpObjectId oid) { 594 595 ComparableSnmpObjectId coid= new ComparableSnmpObjectId(oid); 596 597 if (coid.isLeaf()) 598 { 599 coid = coid.removeLastPart(); 600 } 601 BindEntry be = (BindEntry)bindings.get(coid); 602 603 return be; 604 } 605 606 612 private ComparableSnmpObjectId getNextOid(final ComparableSnmpObjectId oid, boolean stayInSubtree) { 613 ComparableSnmpObjectId coid = new ComparableSnmpObjectId(oid); 614 615 616 if (coid.isLeaf()) 617 coid = coid.removeLastPart(); 618 619 SortedSet ret; 620 ret= oidKeys.tailSet(oid); Iterator it = ret.iterator(); 622 ComparableSnmpObjectId roid=null; 623 624 631 if (it.hasNext()) 632 { 633 roid = (ComparableSnmpObjectId)it.next(); } 635 636 if (roid == null) 637 { 638 return null; } 640 641 if (roid.compareTo(coid)==0) { 643 if (it.hasNext()) 645 { 646 roid = (ComparableSnmpObjectId)it.next(); 647 } 648 else 649 { 650 roid = null; } 652 } 653 654 657 if (stayInSubtree && roid != null) 658 { 659 ComparableSnmpObjectId parent = coid.removeLastPart(); 660 if (!parent.isRootOf(roid)) 661 roid = null; 662 } 663 664 return roid; 665 } 666 667 668 670 675 private class BindEntry implements Comparable { 676 private final ComparableSnmpObjectId oid; 677 678 private ObjectName mbean; 679 private Attribute attr; 680 private String mName; 681 private String aName; 682 private boolean isReadWrite = false; 683 684 694 BindEntry(final String oidString, final String mbName, final String attrName) { 695 this(new ComparableSnmpObjectId(oidString), 696 mbName, 697 attrName); 698 } 699 700 706 BindEntry(final ComparableSnmpObjectId coid, final String mbName, final String attrName) { 707 oid = coid; 708 this.mName = mbName; 709 this.aName = attrName; 710 try 711 { 712 mbean = new ObjectName (mbName); 713 attr = new Attribute (attrName, null); 714 715 } 716 catch (Exception e) 717 { 718 log.warn(e.toString()); 719 mName = "-unset-"; 720 aName = "-unset-"; 721 } 722 } 723 724 727 public String toString() { 728 StringBuffer buf = new StringBuffer (); 729 buf.append("[oid="); 730 buf.append(oid).append(", mbean="); 731 buf.append(mName).append(", attr="); 732 buf.append(aName).append(", rw="); 733 buf.append(isReadWrite).append("]"); 734 735 return buf.toString(); 736 } 737 738 public Attribute getAttr() { 739 return attr; 740 } 741 742 public ObjectName getMbean() 743 { 744 return mbean; 745 } 746 747 public ComparableSnmpObjectId getOid() 748 { 749 return oid; 750 } 751 752 753 760 public int compareTo(Object other) 761 { 762 if (other == null) 763 throw new NullPointerException ("Can't compare to NULL"); 764 765 if (!(other instanceof BindEntry)) 766 throw new ClassCastException ("Parameter is no BindEntry"); 767 768 if (this.equals(other)) 770 return 0; 771 772 BindEntry obe = (BindEntry) other; 773 if (getOid().equals(obe.getOid())) 774 return 0; 775 776 int res =oid.compare(obe.getOid()); 777 return res; 778 } 779 780 } 781 782 } 783 | Popular Tags |