📄 agentconfigmanager.java
字号:
/*_############################################################################
_##
_## SNMP4J-Agent - AgentConfigManager.java
_##
_## Copyright (C) 2005-2008 Frank Fock (SNMP4J.org)
_##
_## Licensed 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.snmp4j.agent;
import java.io.*;
import java.util.*;
import org.snmp4j.*;
import org.snmp4j.agent.cfg.*;
import org.snmp4j.agent.io.*;
import org.snmp4j.agent.mo.snmp.*;
import org.snmp4j.agent.mo.snmp4j.*;
import org.snmp4j.agent.security.*;
import org.snmp4j.agent.version.*;
import org.snmp4j.log.*;
import org.snmp4j.mp.*;
import org.snmp4j.security.*;
import org.snmp4j.smi.*;
import org.snmp4j.util.*;
/**
* The <code>AgentConfigManager</code> is the main component of a SNMP4J-Agent.
* It puts together agent configuration and agent components like command
* processor, message dispatcher, managed objects and server, USM, VACM, etc.
*
* @author Frank Fock
* @version 1.2
* @since 1.2
*/
public class AgentConfigManager implements Runnable {
private static final LogAdapter logger =
LogFactory.getLogger(AgentConfigManager.class);
public static final int STATE_CREATED = 0;
public static final int STATE_INITIALIZED = 10;
public static final int STATE_CONFIGURED = 20;
public static final int STATE_RESTORED = 30;
public static final int STATE_SUSPENDED = 35;
public static final int STATE_RUNNING = 40;
public static final int STATE_UNSAVED_CHANGES = 45;
public static final int STATE_SAVED = 50;
public static final int STATE_SHUTDOWN = -1;
protected CommandProcessor agent;
protected WorkerPool workerPool;
protected VACM vacm;
protected USM usm;
protected MOServer[] servers;
protected Session session;
protected MessageDispatcher dispatcher;
protected OctetString engineID;
protected ProxyForwarder proxyForwarder;
protected NotificationOriginator notificationOriginator;
protected MOInputFactory configuration;
protected MOPersistenceProvider persistenceProvider;
protected int persistenceImportMode = ImportModes.UPDATE_CREATE;
protected EngineBootsProvider engineBootsProvider;
// mandatory standard MIBs
protected SNMPv2MIB snmpv2MIB;
protected SnmpTargetMIB targetMIB;
protected SnmpCommunityMIB communityMIB;
protected SnmpNotificationMIB notificationMIB;
protected SnmpFrameworkMIB frameworkMIB;
protected UsmMIB usmMIB;
protected VacmMIB vacmMIB;
// optional standard MIBs
protected SnmpProxyMIB proxyMIB;
// optional SNMP4J MIBs
protected Snmp4jLogMib snmp4jLogMIB;
protected Snmp4jConfigMib snmp4jConfigMIB;
protected OctetString sysDescr =
new OctetString("SNMP4J-Agent "+
VersionInfo.getVersion()+" [" +
org.snmp4j.version.VersionInfo.getVersion()+"]"+
" - "+System.getProperty("os.name","")+
" - "+System.getProperty("os.arch")+
" - "+System.getProperty("os.version"));
protected OID sysOID = new OID("1.3.6.1.4.1.4976.10");
protected Integer32 sysServices = new Integer32(72);
protected OctetString defaultContext;
protected AgentState runState = new AgentState();
/**
* Creates a SNMP agent configuration which can be run by calling
* {@link #run()} later.
*
* @param agentsOwnEngineID
* the authoritative engine ID of the agent.
* @param messageDispatcher
* the MessageDispatcher to use. The message dispatcher must be configured
* outside, i.e. transport mappings have to be added before this
* constructor is being called.
* @param vacm
* a view access control model. Typically, this parameter is set to
* <code>null</code> to use the default VACM associated with the
* <code>VacmMIB</code>.
* @param moServers
* the managed object server(s) that server the managed objects available
* to this agent.
* @param workerPool
* the <code>WorkerPool</code> to be used to process incoming request.
* @param configurationFactory
* a <code>MOInputFactory</code> that creates a <code>MOInput</code> stream
* with containing serialized ManagedObject information with the agent's
* configuration or <code>null</code> otherwise.
* @param persistenceProvider
* the primary <code>MOPersistenceProvider</code> to be used to load
* and store persistent MOs.
* @param engineBootsProvider
* the provider of engine boots counter.
*/
public AgentConfigManager(OctetString agentsOwnEngineID,
MessageDispatcher messageDispatcher,
VACM vacm,
MOServer[] moServers,
WorkerPool workerPool,
MOInputFactory configurationFactory,
MOPersistenceProvider persistenceProvider,
EngineBootsProvider engineBootsProvider) {
this.engineID = agentsOwnEngineID;
this.dispatcher = messageDispatcher;
this.vacm = vacm;
this.servers = moServers;
this.workerPool = workerPool;
this.configuration = configurationFactory;
this.engineBootsProvider = engineBootsProvider;
this.persistenceProvider = persistenceProvider;
}
/**
* Initializes, configures, restores agent state, and then launches the
* SNMP agent depending on its current run state. For example, if
* {@link #initialize()} has not yet been called it will be called before
* the agent is being configured in the next step.
* <p>
* See also {@link #initialize()}, {@link #configure()},
* {@link #restoreState()}, and {@link #launch()}.
*/
public void run() {
if (runState.getState() < STATE_INITIALIZED) {
initialize();
}
if (runState.getState() < STATE_CONFIGURED) {
configure();
}
if (runState.getState() < STATE_RESTORED) {
restoreState();
}
if (runState.getState() < STATE_RUNNING) {
launch();
}
}
/**
* Launch the agent by registering and lauching (i.e., set to listen mode)
* transport mappings.
*/
protected void launch() {
dispatcher.removeCommandResponder(agent);
dispatcher.addCommandResponder(agent);
registerTransportMappings();
try {
launchTransportMappings();
}
catch (IOException ex) {
String txt =
"Could not put all transport mappings in listen mode: "+
ex.getMessage();
logger.error(txt, ex);
runState.addError(new ErrorDescriptor(txt, runState.getState(),
STATE_RUNNING, ex));
}
runState.advanceState(STATE_RUNNING);
fireLaunchNotifications();
}
/**
* Fire notifications after agent start, i.e. sending a coldStart trap.
*/
protected void fireLaunchNotifications() {
if (notificationOriginator != null) {
notificationOriginator.notify(new OctetString(), SnmpConstants.coldStart,
new VariableBinding[0]);
}
}
/**
* Continues processing of SNMP requests by coupling message dispatcher and
* agent. To succeed, the current state of the agent must be
* {@link #STATE_SUSPENDED}.
*
* @return
* <code>true</code> if the running state could be restored,
* <code>false</code> otherwise.
*/
public boolean continueProcessing() {
if (runState.getState() == STATE_SUSPENDED) {
dispatcher.removeCommandResponder(agent);
dispatcher.addCommandResponder(agent);
runState.setState(STATE_RUNNING);
return true;
}
return false;
}
/**
* Suspends processing of SNMP requests. This call decouples message
* dispatcher and agent. All transport mappings remain unchanged and thus
* all ports remain opened.
*/
public void suspendProcessing() {
dispatcher.removeCommandResponder(agent);
runState.setState(STATE_SUSPENDED);
}
/**
* Shutdown the agent by closing the internal SNMP session - including the
* transport mappings provided through the configured
* {@link MessageDispatcher} and then store the agent state to persistent
* storage (if available).
*/
public void shutdown() {
suspendProcessing();
unregisterMIBs(null);
try {
session.close();
session = null;
}
catch (IOException ex) {
logger.warn("Failed to close SNMP session: "+ex.getMessage());
}
saveState();
runState.setState(STATE_SHUTDOWN);
}
/**
* Registers a shutdown hook <code>Thread</code> at the {@link Runtime}
* instance.
*/
public void registerShutdownHook() {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
shutdown();
}
});
}
public void initSnmp4jLogMIB() {
snmp4jLogMIB = new Snmp4jLogMib();
}
public void initSnmp4jConfigMIB(MOPersistenceProvider[] persistenceProvider) {
snmp4jConfigMIB = new Snmp4jConfigMib(snmpv2MIB.getSysUpTime());
snmp4jConfigMIB.setSnmpCommunityMIB(communityMIB);
if (this.persistenceProvider != null) {
snmp4jConfigMIB.setPrimaryProvider(this.persistenceProvider);
}
if (persistenceProvider != null) {
for (int i = 0; i < persistenceProvider.length; i++) {
if (persistenceProvider[i] != this.persistenceProvider) {
snmp4jConfigMIB.addPersistenceProvider(persistenceProvider[i]);
}
}
}
}
protected void initSecurityModels(EngineBootsProvider engineBootsProvider) {
usm = createUSM();
SecurityModels.getInstance().addSecurityModel(usm);
frameworkMIB = new SnmpFrameworkMIB(usm, dispatcher.getTransportMappings());
}
protected void initMessageDispatcherWithMPs(MessageDispatcher mp) {
mp.addMessageProcessingModel(new MPv1());
mp.addMessageProcessingModel(new MPv2c());
MPv3 mpv3 = new MPv3(agent.getContextEngineID().getValue());
mp.addMessageProcessingModel(mpv3);
}
protected void registerTransportMappings() {
ArrayList l = new ArrayList(dispatcher.getTransportMappings());
for (Iterator it = l.iterator(); it.hasNext();) {
TransportMapping tm = (TransportMapping) it.next();
tm.removeTransportListener(dispatcher);
tm.addTransportListener(dispatcher);
}
}
protected void launchTransportMappings() throws IOException {
launchTransportMappings(dispatcher.getTransportMappings());
}
/**
* Puts a list of transport mappings into listen mode.
* @param transportMappings
* a list of {@link TransportMapping} instances.
* @throws IOException
* if a transport cannot listen to incoming messages.
*/
protected static void launchTransportMappings(Collection transportMappings)
throws IOException
{
ArrayList l = new ArrayList(transportMappings);
for (Iterator it = l.iterator(); it.hasNext();) {
TransportMapping tm = (TransportMapping) it.next();
if (!tm.isListening()) {
tm.listen();
}
}
}
/**
* Closes a list of transport mappings.
* @param transportMappings
* a list of {@link TransportMapping} instances.
* @throws IOException
* if a transport cannot be closed.
*/
protected static void stopTransportMappings(Collection transportMappings)
throws IOException
{
ArrayList l = new ArrayList(transportMappings);
for (Iterator it = l.iterator(); it.hasNext();) {
TransportMapping tm = (TransportMapping) it.next();
if (tm.isListening()) {
tm.close();
}
}
}
/**
* Save the state of the agent persistently - if necessary persistent
* storage is available.
*/
public void saveState() {
if (persistenceProvider != null) {
try {
persistenceProvider.store(persistenceProvider.getDefaultURI());
runState.advanceState(STATE_SAVED);
}
catch (IOException ex) {
String txt = "Failed to save agent state: "+ex.getMessage();
logger.error(txt, ex);
runState.addError(new ErrorDescriptor(txt, runState.getState(),
STATE_SAVED, ex));
}
}
}
/**
* Restore a previously persistently saved state - if available.
* @return
* <code>true</code> if the agent state could be restored successfully,
* <code>false</code> otherwise.
*/
public boolean restoreState() {
if (persistenceProvider != null) {
try {
persistenceProvider.restore(persistenceProvider.getDefaultURI(),
persistenceImportMode);
runState.advanceState(STATE_RESTORED);
return true;
}
catch (FileNotFoundException fnf) {
String txt = "Saved agent state not found: "+fnf.getMessage();
logger.warn(txt);
}
catch (IOException ex) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -