| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.synapse.commons.snmp; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.snmp4j.TransportMapping; |
| import org.snmp4j.agent.BaseAgent; |
| import org.snmp4j.agent.CommandProcessor; |
| import org.snmp4j.agent.DuplicateRegistrationException; |
| import org.snmp4j.agent.ManagedObject; |
| import org.snmp4j.agent.io.ImportModes; |
| import org.snmp4j.agent.mo.snmp.*; |
| import org.snmp4j.agent.mo.snmp.SnmpCommunityMIB.SnmpCommunityEntryRow; |
| import org.snmp4j.agent.security.MutableVACM; |
| import org.snmp4j.mp.MPv3; |
| import org.snmp4j.mp.SnmpConstants; |
| import org.snmp4j.security.*; |
| import org.snmp4j.smi.*; |
| import org.snmp4j.transport.TransportMappings; |
| |
| import javax.management.*; |
| import java.io.File; |
| import java.io.IOException; |
| import java.lang.management.ManagementFactory; |
| import java.util.*; |
| |
| /** |
| * SNMP agent which is capable of listening for incoming SNMP GET/GETNEXT requests |
| * and responding to them accordingly. This agent implementation exposed all the |
| * standard Synapse MBeans over SNMP. The view exposed by the agent is read-only as of |
| * now (this may be changed in a future version). The relevant OID mappings are |
| * defined in the SynapseMIBUtils class. Each MBean attribute becomes a leaf in the MIB |
| * exposed by the agent. For each MBean, attributes are arranged in the alphabetical |
| * order for OID assignment. MBean APIs rarely change. Therefore this scheme will |
| * guarantee a fairly consistent OID scheme. |
| */ |
| class SNMPAgent extends BaseAgent { |
| |
| private static final Log log = LogFactory.getLog(SNMPAgent.class); |
| |
| private static final String FULL_READ_VIEW = "fullReadView"; |
| private static final String GROUP_NAME = "synapseSNMPGroup"; |
| private static final String COMMUNITY_RECORD = "public2public"; |
| |
| private Properties properties; |
| |
| private Set<OID> registeredOIDs = new HashSet<OID>(); |
| private int snmpVersion; |
| |
| public SNMPAgent(Properties properties) { |
| super(new File(SNMPConstants.BC_FILE), new File(SNMPConstants.CONFIG_FILE), |
| new CommandProcessor(new OctetString(MPv3.createLocalEngineID()))); |
| this.properties = properties; |
| |
| String version = getProperty(SNMPConstants.SNMP_VERSION, SNMPConstants.SNMP_DEFAULT_VERSION); |
| if (SNMPConstants.SNMP_VERSION_1.equals(version)) { |
| this.snmpVersion = SnmpConstants.version1; |
| } else if (SNMPConstants.SNMP_VERSION_2_C.equals(version)) { |
| this.snmpVersion = SnmpConstants.version2c; |
| } else { |
| log.warn("Unsupported SNMP version: " + version + " - Using defaults"); |
| this.snmpVersion = SnmpConstants.version1; |
| } |
| } |
| |
| /** |
| * Initialize and start this SNMP agent |
| * |
| * @throws IOException If an error occurs while initializing the agent |
| */ |
| public void start() throws IOException { |
| String context = getProperty(SNMPConstants.SNMP_CONTEXT_NAME, |
| SNMPConstants.SNMP_DEFAULT_CONTEXT_NAME); |
| init(); |
| loadConfig(ImportModes.REPLACE_CREATE); |
| addShutdownHook(); |
| getServer().addContext(new OctetString(context)); |
| finishInit(); |
| run(); |
| sendColdStartNotification(); |
| } |
| |
| @Override |
| protected void initTransportMappings() throws IOException { |
| String host = getProperty(SNMPConstants.SNMP_HOST, SNMPConstants.SNMP_DEFAULT_HOST); |
| int port = Integer.parseInt(getProperty(SNMPConstants.SNMP_PORT, |
| String.valueOf(SNMPConstants.SNMP_DEFAULT_PORT))); |
| String address = host + "/" + port; |
| Address adr = GenericAddress.parse(address); |
| TransportMapping tm = |
| TransportMappings.getInstance().createTransportMapping(adr); |
| transportMappings = new TransportMapping[] { tm }; |
| log.info("SNMP transport adapter initialized on udp:" + address); |
| } |
| |
| @Override |
| protected void registerManagedObjects() { |
| log.info("Initializing Synapse SNMP MIB"); |
| MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); |
| Set<ObjectInstance> instances = mbs.queryMBeans(null, null); |
| |
| try { |
| for (ObjectInstance instance : instances) { |
| ObjectName objectName = instance.getObjectName(); |
| if (objectName.getDomain().equals("org.apache.synapse")) { |
| String oidString = SynapseMIBUtils.getOID(objectName); |
| if (oidString == null) { |
| continue; |
| } |
| |
| MBeanInfo info = mbs.getMBeanInfo(objectName); |
| MBeanAttributeInfo[] attributes = info.getAttributes(); |
| List<String> attributeNames = new ArrayList<String>(); |
| List<String> mapAttributes = new ArrayList<String>(); |
| for (MBeanAttributeInfo attributeInfo : attributes) { |
| attributeNames.add(attributeInfo.getName()); |
| if (Map.class.getName().equals(attributeInfo.getType())) { |
| mapAttributes.add(attributeInfo.getName()); |
| } |
| } |
| Collections.sort(attributeNames); |
| |
| doRegister(attributeNames, mapAttributes, oidString, objectName); |
| } |
| } |
| } catch (Exception e) { |
| log.error("Error while initializing the SNMP MIB", e); |
| } |
| } |
| |
| private void doRegister(List<String> attributeNames, List<String> mapAttributes, |
| String oidString, ObjectName objectName) { |
| |
| for (int i = 0; i < attributeNames.size(); i++) { |
| String attributeName = attributeNames.get(i); |
| if (mapAttributes.contains(attributeName)) { |
| continue; |
| } |
| OID oid = new OID(oidString + "." + (i + 1) + ".0"); |
| if (log.isDebugEnabled()) { |
| log.debug("Registering " + objectName + "@" + attributeName + |
| " as OID: " + oid); |
| } |
| try { |
| server.register(new SynapseMOScalar( |
| oid, objectName, attributeName, snmpVersion), null); |
| registeredOIDs.add(oid); |
| } catch (DuplicateRegistrationException e) { |
| log.error("Error while registering the OID: " + oid + " for object: " + |
| objectName + " and attribute: " + attributeName, e); |
| } |
| } |
| } |
| |
| @Override |
| protected void unregisterManagedObjects() { |
| if (log.isDebugEnabled()) { |
| log.debug("Cleaning up registered OIDs"); |
| } |
| |
| for (OID oid : registeredOIDs) { |
| ManagedObject mo = server.getManagedObject(oid, null); |
| if (mo != null) { |
| server.unregister(mo, null); |
| } |
| } |
| registeredOIDs.clear(); |
| } |
| |
| @Override |
| protected void addUsmUser(USM usm) { |
| |
| } |
| |
| @Override |
| protected void addNotificationTargets(SnmpTargetMIB snmpTargetMIB, |
| SnmpNotificationMIB snmpNotificationMIB) { |
| |
| } |
| |
| @Override |
| protected void addViews(VacmMIB vacm) { |
| String communityString = getProperty(SNMPConstants.SNMP_COMMUNITY_NAME, |
| SNMPConstants.SNMP_DEFAULT_COMMUNITY_NAME); |
| String securityName = getProperty(SNMPConstants.SNMP_SECURITY_NAME, |
| SNMPConstants.SNMP_DEFAULT_SECURITY_NAME); |
| |
| int securityModel = SecurityModel.SECURITY_MODEL_SNMPv1; |
| if (snmpVersion == SnmpConstants.version2c) { |
| securityModel = SecurityModel.SECURITY_MODEL_SNMPv2c; |
| } |
| |
| vacm.addGroup(securityModel, |
| new OctetString(securityName), |
| new OctetString(GROUP_NAME), |
| StorageType.nonVolatile); |
| |
| vacm.addAccess(new OctetString(GROUP_NAME), new OctetString(communityString), |
| securityModel, |
| SecurityLevel.NOAUTH_NOPRIV, |
| MutableVACM.VACM_MATCH_EXACT, |
| new OctetString(FULL_READ_VIEW), // read permission granted |
| new OctetString(), // no write permissions |
| new OctetString(), // no notify permissions |
| StorageType.nonVolatile); |
| |
| vacm.addViewTreeFamily(new OctetString(FULL_READ_VIEW), |
| new OID(SNMPConstants.SYNAPSE_OID_BRANCH), |
| new OctetString(), |
| VacmMIB.vacmViewIncluded, |
| StorageType.nonVolatile); |
| } |
| |
| @Override |
| protected void addCommunities(SnmpCommunityMIB communityMIB) { |
| String community = getProperty(SNMPConstants.SNMP_COMMUNITY_NAME, |
| SNMPConstants.SNMP_DEFAULT_COMMUNITY_NAME); |
| String securityName = getProperty(SNMPConstants.SNMP_SECURITY_NAME, |
| SNMPConstants.SNMP_DEFAULT_SECURITY_NAME); |
| String context = getProperty(SNMPConstants.SNMP_CONTEXT_NAME, |
| SNMPConstants.SNMP_DEFAULT_CONTEXT_NAME); |
| |
| if (log.isDebugEnabled()) { |
| log.debug("Registering SNMP community string: " + community + " under the " + |
| "context: " + context); |
| } |
| |
| Variable[] com2sec = new Variable[] { |
| new OctetString(community), // community name |
| new OctetString(securityName), // security name |
| getAgent().getContextEngineID(), // local engine ID |
| new OctetString(context), // default context name |
| new OctetString(), // transport tag |
| new Integer32(StorageType.nonVolatile), // storage type |
| new Integer32(RowStatus.active) // row status |
| }; |
| SnmpCommunityEntryRow row = |
| communityMIB.getSnmpCommunityEntry().createRow( |
| new OctetString(COMMUNITY_RECORD).toSubIndex(true), com2sec); |
| communityMIB.getSnmpCommunityEntry().addRow(row); |
| } |
| |
| private String getProperty(String name, String def) { |
| String value = properties.getProperty(name); |
| if (value == null) { |
| value = def; |
| } |
| return value; |
| } |
| } |