Package org.snmp4j.agent.agentx.master

Source Code of org.snmp4j.agent.agentx.master.AgentXMasterAgent

/*_############################################################################
  _##
  _##  SNMP4J-AgentX - AgentXMasterAgent.java 
  _##
  _##  Copyright (C) 2005-2009  Frank Fock (SNMP4J.org)
  _## 
  _##  This program is free software; you can redistribute it and/or modify
  _##  it under the terms of the GNU General Public License version 2 as
  _##  published by the Free Software Foundation.
  _##
  _##  This program is distributed in the hope that it will be useful,
  _##  but WITHOUT ANY WARRANTY; without even the implied warranty of
  _##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  _##  GNU General Public License for more details.
  _##
  _##  You should have received a copy of the GNU General Public License
  _##  along with this program; if not, write to the Free Software
  _##  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  _##  MA  02110-1301  USA
  _## 
  _##########################################################################*/

package org.snmp4j.agent.agentx.master;

import java.io.File;

import org.snmp4j.TransportMapping;
import org.snmp4j.agent.DuplicateRegistrationException;
import org.snmp4j.agent.agentx.AgentX;
import org.snmp4j.agent.agentx.AgentXMessageDispatcherImpl;
import org.snmp4j.agent.agentx.AgentXProtocol;
import org.snmp4j.log.LogAdapter;
import org.snmp4j.log.LogFactory;
import org.snmp4j.mp.MPv3;
import org.snmp4j.smi.IpAddress;
import org.snmp4j.smi.OctetString;
import org.snmp4j.transport.ConnectionOrientedTransportMapping;
import org.snmp4j.transport.TransportStateEvent;
import org.snmp4j.transport.TransportStateListener;
import java.net.InetAddress;
import org.snmp4j.agent.AgentConfigManager;
import org.snmp4j.agent.cfg.EngineBootsProvider;
import org.snmp4j.agent.MOServer;
import org.snmp4j.MessageDispatcher;
import org.snmp4j.agent.io.MOPersistenceProvider;
import org.snmp4j.util.WorkerPool;
import org.snmp4j.agent.io.MOInputFactory;
import org.snmp4j.agent.security.VACM;
import org.snmp4j.MessageDispatcherImpl;
import org.snmp4j.agent.DefaultMOServer;
import org.snmp4j.util.ThreadPool;
import org.snmp4j.agent.io.DefaultMOPersistenceProvider;
import org.snmp4j.agent.cfg.EngineBootsCounterFile;
import org.snmp4j.agent.CommandProcessor;
import org.snmp4j.agent.agentx.version.VersionInfo;
import java.io.IOException;

/**
* The <code>AgentXMasterAgent</code> is the base agent class for
* AgentX master agents. It extends the {@link AgentConfigManager} class
* provided by SNMP4J-Agent.
* <p>
* To implement a master agent, simply extend this class instead of
* {@link AgentConfigManager} as you would do for a non-AgentX agent.
*
* @author Frank Fock
* @version 1.1
*/
public class AgentXMasterAgent extends AgentConfigManager implements
    TransportStateListener {

  private static final LogAdapter LOGGER =
      LogFactory.getLogger(AgentXMasterAgent.class);

  private static short maxGetBulkRepetitions = Short.MAX_VALUE;
  private AgentX agentX;
  private AgentXCommandProcessor commandProcessor;
  private AgentXQueue queue = new AgentXQueue();
  private AgentXMib agentXMIB;
  private OctetString localEngineID =
      new OctetString(MPv3.createLocalEngineID());
  private boolean localhostSubagentsOnly;

  /**
   * 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 AgentXMasterAgent(OctetString agentsOwnEngineID,
                           MessageDispatcher messageDispatcher,
                           VACM vacm,
                           MOServer[] moServers,
                           WorkerPool workerPool,
                           MOInputFactory configurationFactory,
                           MOPersistenceProvider persistenceProvider,
                           EngineBootsProvider engineBootsProvider) {
    super(agentsOwnEngineID, messageDispatcher, vacm, moServers,
          workerPool, configurationFactory, persistenceProvider,
          engineBootsProvider);
    sysDescr.setValue("SNMP4J-AgentX "+
                      VersionInfo.getVersion()+" [" +
                      org.snmp4j.agent.version.VersionInfo.getVersion()+
                      ","+org.snmp4j.version.VersionInfo.getVersion()+
                      "]"+
                      " - "+System.getProperty("os.name","")+
                      " - "+System.getProperty("os.arch")+
                      " - "+System.getProperty("os.version"));
    agentX = new AgentX(new AgentXMessageDispatcherImpl());
  }

  private AgentXMasterAgent(File bootCounterFile,
                            File configFile,
                            MOServer[] servers) {
    this(new OctetString(MPv3.createLocalEngineID()),
         new MessageDispatcherImpl(),
         null,
         servers,
         ThreadPool.create("AgentXMasterAgent", 3),
         null,
         new DefaultMOPersistenceProvider(servers,
                                          configFile.getPath()),
         new EngineBootsCounterFile(bootCounterFile));
    agentX = new AgentX(new AgentXMessageDispatcherImpl());
  }

  /**
   * Creates a simple AgentX master agent using a boot counter file and
   * config file for persistent storage.
   *
   * @param bootCounterFile
   *    a file that stores the boot counter.
   * @param configFile
   *    a file that stores persistent MIB data.
   */
  public AgentXMasterAgent(File bootCounterFile,
                           File configFile) {
    this(bootCounterFile, configFile, new MOServer[] { new DefaultMOServer() });
  }

  public void initialize() {
    super.initialize();
  }

  /**
   * Creates the command processor.
   *
   * @param engineID
   *    the engine ID of the agent.
   * @return
   *    a new CommandProcessor instance.
   */
  protected CommandProcessor createCommandProcessor(OctetString engineID) {
    AgentXCommandProcessor cp =
        new AgentXCommandProcessor(engineID, queue, agentX, servers);
    agentX.addCommandResponder(cp);
    this.agentXMIB = new AgentXMib(cp);
    cp.setNotificationOriginator(getNotificationOriginator());
    cp.addAgentXMasterListener(this.agentXMIB);
    this.commandProcessor = cp;
    return cp;
  }

  public void addAgentXTransportMapping(TransportMapping transport) {
    agentX.getMessageDispatcher().addTransportMapping(transport);
    if (transport instanceof ConnectionOrientedTransportMapping) {
      ConnectionOrientedTransportMapping cotm =
          (ConnectionOrientedTransportMapping)transport;
      cotm.addTransportStateListener(this);
      cotm.setConnectionTimeout(0);
      cotm.setMessageLengthDecoder(new AgentXProtocol());
    }
  }

  public void removeAgentXTransportMapping(TransportMapping transport) {
    agentX.getMessageDispatcher().removeTransportMapping(transport);
    if (transport instanceof ConnectionOrientedTransportMapping) {
      ConnectionOrientedTransportMapping cotm =
          (ConnectionOrientedTransportMapping)transport;
      cotm.removeTransportStateListener(this);
    }
  }

  /**
   * Gets the upper limit for AgentX Get Bulk repetitions field send on behalf
   * of all master agents of this JVM.
   * @return
   *    the upper limit for the maximum repetitions field for AgentX Get Bulk
   *    requests.
   * @see #setMaxGetBulkRepetitions
   */
  public static short getMaxGetBulkRepetitions() {
    return maxGetBulkRepetitions;
  }

  public AgentXMib getAgentXMIB() {
    return agentXMIB;
  }

  public AgentXCommandProcessor getCommandProcessor() {
    return commandProcessor;
  }

  public OctetString getLocalEngineID() {
    return localEngineID;
  }

  /**
   * Indicates whether only subagents from the local host or from any host
   * are allowed to connect to this master agent (default is any host).
   * @return
   *    <code>true</code> if only connections from the local host are allowed
   *    and <code>false</code> if connections from any host are allowed.
   */
  public boolean isLocalhostSubagentsOnly() {
    return localhostSubagentsOnly;
  }

  /**
   * Sets the maximum repetitions value used by this master agent for its
   * AgentX Get Bulk requests to subagents. The default is the maximum short
   * value. The SNMP GETBULK request already defines a maximum repetitions
   * value that is always the upper limit also for AgentX Get Bulk requests on
   * its behalf.
   * <p>
   * The NET-SNMP AgentX sub-agent has a bug in its AgentX Get Bulk processing
   * that causes endless loops in the sub-agent when the max-repetitions value
   * is greater than one. Since this bug is in NET-SNMP since v4.2 and still
   * present in version 5.4, it is likely, that you will need to set this
   * value to one, if your master agent should ever communicate with a NET-SNMP
   * sub-agent.
   *
   * @param maxRepetitions
   *    the upper limit of the maximum repetitions for AgentX Get Bulk
   *    sub-requests.
   */
  public static void setMaxGetBulkRepetitions(short maxRepetitions) {
    if (maxRepetitions < 1) {
      throw new IllegalArgumentException(
          "Max repetitions needs an unsigned value");
    }
    maxGetBulkRepetitions = maxRepetitions;
  }

  public void setLocalEngineID(OctetString localEngineID) {
    this.localEngineID = localEngineID;
  }

  /**
   * Sets the local host only connection filter flag.
   * @param localhostSubagentsOnly
   *    <code>true</code> if only connections from the local host are allowed
   *    and <code>false</code> if connections from any host are allowed.
   */
  public void setLocalhostSubagentsOnly(boolean localhostSubagentsOnly) {
    this.localhostSubagentsOnly = localhostSubagentsOnly;
  }

  public void connectionStateChanged(TransportStateEvent change) {
    if (localhostSubagentsOnly &&
        (change.getNewState() == TransportStateEvent.STATE_CONNECTED) &&
        (change.getPeerAddress() instanceof IpAddress)) {
      IpAddress peerAddress = (IpAddress)change.getPeerAddress();
      if (!peerAddress.getInetAddress().isLoopbackAddress()) {
        LOGGER.warn("Connection attempt made from non loopback (i.e. local) address '"+
                    peerAddress+"' which will be ignored");
        change.setCancelled(true);
        return;
      }
    }
    ((AgentXCommandProcessor)agent).connectionStateChanged(change);
  }

  protected void registerMIBs(OctetString context) throws
      DuplicateRegistrationException
  {
    super.registerMIBs(context);
    try {
      agentXMIB.registerMOs(agent.getServer(context), context);
    }
    catch (DuplicateRegistrationException ex) {
      String txt = "Unable to register AgentX MIB";
      LOGGER.error(txt, ex);
      throw new DuplicateRegistrationException(txt);
    }
  }

  protected void unregisterMIBs(OctetString context) {
    agentXMIB.unregisterMOs(agent.getServer(context), null);
  }

  protected void launchTransportMappings() throws IOException {
    super.launchTransportMappings();
    launchTransportMappings(agentX.getMessageDispatcher().getTransportMappings());
  }

  public void shutdown() {
    try {
      stopTransportMappings(agentX.getMessageDispatcher().getTransportMappings());
    }
    catch (IOException ex) {
      LOGGER.error("Failed to shutdown AgentX: "+ex.getMessage(), ex);
    }
    super.shutdown();
  }

}
TOP

Related Classes of org.snmp4j.agent.agentx.master.AgentXMasterAgent

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.