Class MOXodusPersistence

  • All Implemented Interfaces:
    EventListener, org.snmp4j.agent.mo.MOChangeListener

    public class MOXodusPersistence
    extends Object
    implements org.snmp4j.agent.mo.MOChangeListener
    The MOXodusPersistence class provides persistent storage for SNMP4J-Agent using the MOXodusPersistenceProvider wrapper that actually implements the MOPersistenceProvider interface of SNMP4J-Agent. As storage engine, the Xodus open source (Apache 2 License) DB is used. See https://github.com/JetBrains/xodus} for details. The database approach has the following advantages compared to the standard sequential persistence provider coming with SNMP4J-Agent:
    • Only changed objects are written again to disk. The default DefaultMOPersistenceProvider needs to save all objects in a sequence.
    • DB size is smaller - if changes are limited to approximately less than 40% of the MIB objects during runtime.
    • Agent shutdown is much faster because no objects need to be saved anymore.
    • No data loss if agent is killed.
    The following sample code from SampleAgent illustrates how this class is created and assigned to the agent during its initialization.
         File configFile = new File(myConfigDir);
         MOXodusPersistence moXodusPersistence = new MOXodusPersistence(moServers, Environments.newInstance(configFile));
         MOXodusPersistenceProvider moXodusPersistenceProvider = new MOXodusPersistenceProvider(moXodusPersistence);
         OctetString defaultEngineID = new OctetString(MPv3.createLocalEngineID());
         OctetString engineID = moXodusPersistenceProvider.getEngineId(defaultEngineID);
         ...
         agent = new AgentConfigManager(engineID, messageDispatcher, null, moServers, ThreadPool.create("SampleAgent", 3),
                                        (defaultEngineID == engineID) ? configurationFactory : null,
                                        moXodusPersistenceProvider,
                                        new EngineBootsCounterFile(bootCounterFile), null, dhKickstartParameters);
         agent.addAgentStateListener(new AgentStateListener() {
             public void agentStateChanged(AgentConfigManager agentConfigManager, AgentState newState) {
                 switch (newState.getState()) {
                     case AgentState.STATE_INITIALIZED:
                         moXodusPersistence.registerChangeListenersWithServer(server);
                         break;
                     case AgentState.STATE_SHUTDOWN:
                         moXodusPersistence.unregisterChangeListenersWithServer(server);
                         break;
                 }
             }
         });
    
     
    Since:
    3.0
    Version:
    3.2.0
    Author:
    Frank Fock
    • Constructor Detail

      • MOXodusPersistence

        public MOXodusPersistence​(org.snmp4j.agent.MOServer[] moServers,
                                  jetbrains.exodus.env.Environment environment)
        Creates a new MOXodusPersistence from an array of MOServer instances and an Xodus Environment. The data of modified objects are stored whenever a corresponding MOChangeEvent is received.
        Parameters:
        moServers - the ManagedObject servers of the agent to be supported with persistent storage capabilities by this object.
        environment - the Xodus environment that actually holds the persistent data.
      • MOXodusPersistence

        public MOXodusPersistence​(org.snmp4j.agent.MOServer[] moServers,
                                  jetbrains.exodus.env.Environment environment,
                                  MOXodusPersistence.SavingStrategy savingStrategy)
        Creates a new MOXodusPersistence from an array of MOServer instances and an Xodus Environment.
        Parameters:
        moServers - the ManagedObject servers of the agent to be supported with persistent storage capabilities by this object.
        environment - the Xodus environment that actually holds the persistent data.
        savingStrategy - defines when and how modified objects of the agent should be saved into persistent storage.
    • Method Detail

      • isIgnoreChangeListenerEvents

        public boolean isIgnoreChangeListenerEvents()
      • setIgnoreChangeListenerEvents

        public void setIgnoreChangeListenerEvents​(boolean ignoreChangeListenerEvents)
        Defines whether MOChangeEvents should be ignored or not. This method can be used to disable persistent storage activities when the default strategy MOXodusPersistence.SavingStrategy.onChangeEventsOnly is active and other bulk operations change MIB data in the agent. When activating the processing of MOChangeEvents is activated again by setting this value to false, the missed events will not be processed again. Thus, if data has changed that need to be persistent, the save() has to be called with strategy MOXodusPersistence.SavingStrategy.checkForModificationsOnSave or MOXodusPersistence.SavingStrategy.fullDumpOnSave manually.
        Parameters:
        ignoreChangeListenerEvents - true to disable event processing and saving changes triggered by MOChangeEvents.
      • getEnvironment

        public jetbrains.exodus.env.Environment getEnvironment()
      • isContinuousChangeListening

        public boolean isContinuousChangeListening()
      • registerChangeListenersWithServer

        public void registerChangeListenersWithServer​(org.snmp4j.agent.MOServer moServer)
        Register this object as MOChangeListener on all RandomAccessManagedObject instances in the provided MOServer.
        Parameters:
        moServer - a MOServer holding RandomAccessManagedObjects that should be persisted.
      • unregisterChangeListenersWithServer

        public void unregisterChangeListenersWithServer​(org.snmp4j.agent.MOServer moServer)
        Removes a former registration of this object as MOChangeListener on all RandomAccessManagedObject instances in the provided MOServer.
        Parameters:
        moServer - a MOServer holding RandomAccessManagedObjects that should not be persisted anymore.
      • isContextLoadable

        public boolean isContextLoadable​(org.snmp4j.smi.OctetString context)
        Checks if there is already MIB data stored for the specified context. To check the default context (null), please use the empty OctetString. This method should be called before calling load(ImportMode) because afterwards it will return true for all contexts that were present in getMOServer() and for the default context (empty context).
        Parameters:
        context - a non-null context string. The empty (zero length) OctetString represents the default context.
        Returns:
        true if there has been data stored for this context - even if no RandomAccessManagedObject actually has stored any data.
        Since:
        3.0.1
      • load

        public void load​(org.snmp4j.agent.io.ImportMode importMode)
        Load the contents of all RandomAccessManagedObjects using RandomAccessManagedObject.importInstance(OID, List, ImportMode) calls. The provided ImportMode thereby defines how the data handles existing data. Data is loaded for all contexts and managed objects found in the {link MOServer} instances provided during object creation. While loading, the member ignoreChangeListenerEvents is set to true to ignore updates caused by loading data into the RandomAccessManagedObject instances.
        Parameters:
        importMode - controls how existing data is used or not used during import.
      • createStore

        @NotNull
        protected jetbrains.exodus.env.Store createStore​(jetbrains.exodus.env.Transaction txn,
                                                         org.snmp4j.smi.OctetString context)
      • storeNameFromContext

        protected String storeNameFromContext​(org.snmp4j.smi.OctetString context)
        Return a string store name for the provided SNMPv3 context.
        Parameters:
        context - a context name or null for the default context.
        Returns:
        a store name, by default context == null ? "" : context.toHexString().
        Since:
        3.0.1
      • getMOServer

        public org.snmp4j.agent.MOServer[] getMOServer()
      • runSynchronization

        protected void runSynchronization​(Map<org.snmp4j.smi.OctetString,jetbrains.exodus.env.Store> stores,
                                          jetbrains.exodus.env.Transaction txn,
                                          org.snmp4j.agent.io.ImportMode importMode,
                                          Iterator<Map.Entry<org.snmp4j.agent.MOScope,org.snmp4j.agent.ManagedObject<?>>> moIterator)
      • decodeInstanceData

        protected List<org.snmp4j.smi.VariableBinding> decodeInstanceData​(jetbrains.exodus.ByteIterable rawData)
      • encodeInstanceData

        protected byte[] encodeInstanceData​(List<org.snmp4j.smi.VariableBinding> vbs)
      • decodeVariableBinding

        protected org.snmp4j.smi.VariableBinding decodeVariableBinding​(org.snmp4j.asn1.BERInputStream inputStream)
                                                                throws IOException
        Throws:
        IOException
      • encodeVariableBinding

        protected void encodeVariableBinding​(org.snmp4j.smi.VariableBinding vb,
                                             org.snmp4j.asn1.BEROutputStream outputStream)
                                      throws IOException
        Throws:
        IOException
      • getKey

        protected jetbrains.exodus.ByteIterable getKey​(org.snmp4j.smi.OID oid,
                                                       org.snmp4j.smi.OID instanceID)
      • getKeyOid

        protected org.snmp4j.smi.OID getKeyOid​(jetbrains.exodus.ByteIterable key)
      • getIndexOIDLength

        public static int getIndexOIDLength​(int[] value)
      • decodeIndexOID

        public static int[] decodeIndexOID​(org.snmp4j.asn1.BERInputStream is,
                                           org.snmp4j.asn1.BER.MutableByte type)
                                    throws IOException
        Throws:
        IOException
      • beforePrepareMOChange

        public void beforePrepareMOChange​(org.snmp4j.agent.mo.MOChangeEvent changeEvent)
        A ManagedObject change is being prepared. To cancel preparation set the deny reason to a SNMPv2/v3 error status.
        Specified by:
        beforePrepareMOChange in interface org.snmp4j.agent.mo.MOChangeListener
        Parameters:
        changeEvent - the change event object.
      • afterPrepareMOChange

        public void afterPrepareMOChange​(org.snmp4j.agent.mo.MOChangeEvent changeEvent)
        A change has been prepared. Setting the deny reason of the supplied event object will be ignored.
        Specified by:
        afterPrepareMOChange in interface org.snmp4j.agent.mo.MOChangeListener
        Parameters:
        changeEvent - the change event object.
      • beforeMOChange

        public void beforeMOChange​(org.snmp4j.agent.mo.MOChangeEvent changeEvent)
        A ManagedObject change is being committed. To cancel the commit phase set the deny reason to a SNMPv2/v3 error status.

        NOTE: Canceling the commit phase must be avoided. Setting a deny reason has only an effect if DeniableEventObject.isDeniable() returns true. Otherwise, you will need to throw an exception.

        Specified by:
        beforeMOChange in interface org.snmp4j.agent.mo.MOChangeListener
        Parameters:
        changeEvent - the change event object.
      • afterMOChange

        public void afterMOChange​(org.snmp4j.agent.mo.MOChangeEvent changeEvent)
        A change has been committed. Setting the deny reason of the supplied event object will be ignored.
        Specified by:
        afterMOChange in interface org.snmp4j.agent.mo.MOChangeListener
        Parameters:
        changeEvent - the change event object.
      • getContexts

        protected Set<org.snmp4j.smi.OctetString> getContexts​(org.snmp4j.agent.ManagedObject managedObject)