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.5.0
    Author:
    Frank Fock
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void afterMOChange​(org.snmp4j.agent.mo.MOChangeEvent changeEvent)
      A change has been committed.
      void afterPrepareMOChange​(org.snmp4j.agent.mo.MOChangeEvent changeEvent)
      A change has been prepared.
      void beforeMOChange​(org.snmp4j.agent.mo.MOChangeEvent changeEvent)
      A ManagedObject change is being committed.
      void beforePrepareMOChange​(org.snmp4j.agent.mo.MOChangeEvent changeEvent)
      A ManagedObject change is being prepared.
      protected jetbrains.exodus.env.Store createStore​(jetbrains.exodus.env.Transaction txn, org.snmp4j.smi.OctetString context)
      Ceates a Store for a context.
      static int[] decodeIndexOID​(org.snmp4j.asn1.BERInputStream is, org.snmp4j.asn1.BER.MutableByte type)
      Decode a index OID from a BER input stream.
      protected List<org.snmp4j.smi.VariableBinding> decodeInstanceData​(jetbrains.exodus.ByteIterable rawData)
      Decode BER instance data from raw byte stream.
      protected org.snmp4j.smi.VariableBinding decodeVariableBinding​(org.snmp4j.asn1.BERInputStream inputStream)
      Decode a VariableBinding from an BERInputStream.
      static void encodeIndexOID​(OutputStream os, byte type, int[] oid)
      Encodes an index OID.
      protected byte[] encodeInstanceData​(List<org.snmp4j.smi.VariableBinding> vbs)
      Encode instance data from a list of VariableBindings.
      protected void encodeVariableBinding​(org.snmp4j.smi.VariableBinding vb, org.snmp4j.asn1.BEROutputStream outputStream)
      Encode a VariableBinding to a BEROutputStream.
      protected Set<org.snmp4j.smi.OctetString> getContexts​(org.snmp4j.agent.ManagedObject<?> managedObject)
      Get the contexts registered with all MOServer for the given ManagedObject.
      jetbrains.exodus.env.Environment getEnvironment​()
      Gets the Xodus Environment used by this persistent probvider.
      static int getIndexOIDLength​(int[] value)
      Get the index OID length from a index OID raw value.
      protected jetbrains.exodus.ByteIterable getKey​(org.snmp4j.smi.OID oid, org.snmp4j.smi.OID instanceID)
      Gets the key for an OID and instance ID.
      protected org.snmp4j.smi.OID getKeyOid​(jetbrains.exodus.ByteIterable key)
      Gets the OID of a key.
      org.snmp4j.agent.MOScopeComparator getMoScopeComparator​()
      Gets the MOScopeComparator that defines the default order in which ManagedObjects are stored and restored from persistent storage (unless the parameter MOPriorityProvider is used).
      org.snmp4j.agent.MOServer[] getMOServer​()
      Get the associated MOServers.
      MOXodusPersistence.SavingStrategy getSavingStrategy​()
      Gets the saving strategy as defined by MOXodusPersistence.SavingStrategy.
      boolean isContextLoadable​(org.snmp4j.smi.OctetString context)
      Checks if there is already MIB data stored for the specified context.
      boolean isContinuousChangeListening​()
      Return true if the registerChangeListenersWithServer(MOServer) for any server, but unregisterChangeListenersWithServer(MOServer) has not been called yet.
      boolean isIgnoreChangeListenerEvents​()
      Check whether change listener events are actually suppressed (i.e.
      void load​(org.snmp4j.agent.io.ImportMode importMode)  
      void load​(org.snmp4j.agent.io.ImportMode importMode, org.snmp4j.agent.mo.MOPriorityProvider priorityProvider)
      Load the contents of all RandomAccessManagedObjects using RandomAccessManagedObject.importInstance(OID, List, ImportMode) calls.
      void registerChangeListenersWithServer​(org.snmp4j.agent.MOServer moServer)
      Register this object as MOChangeListener on all RandomAccessManagedObject instances in the provided MOServer.
      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)
      Run synchronisation between in memory data and on disk data.
      protected org.snmp4j.agent.ManagedObject<?> runSyncOnBootMO​(jetbrains.exodus.env.Transaction txn, org.snmp4j.agent.MOServer moServer, Map<org.snmp4j.smi.OctetString,jetbrains.exodus.env.Store> stores, org.snmp4j.agent.io.ImportMode importMode, org.snmp4j.agent.mo.MOPriorityProvider priorityProvider, org.snmp4j.smi.OctetString context)
      Run synchronisation on the boot ManagedObject (i.e.
      void save​()
      Saves the data of the MOServers associated with this instance to persistent storage depending on the currently configured MOXodusPersistence.SavingStrategy.
      void save​(org.snmp4j.agent.mo.MOPriorityProvider priorityProvider)
      Saves the data of the MOServers associated with this instance to persistent storage depending on the currently configured MOXodusPersistence.SavingStrategy.
      void setIgnoreChangeListenerEvents​(boolean ignoreChangeListenerEvents)
      Defines whether MOChangeEvents should be ignored or not.
      void setMoScopeComparator​(org.snmp4j.agent.MOScopeComparator moScopeComparator)
      Sets the MOScopeComparator and by this defines the default order in which ManagedObjects are stored and restored from persistent storage as long as parameter MOPriorityProvider of save(MOPriorityProvider) and load(ImportMode, MOPriorityProvider) are not used.
      void setSavingStrategy​(MOXodusPersistence.SavingStrategy savingStrategy)
      Sets the saving strategy for this persistence provider as defined by MOXodusPersistence.SavingStrategy.
      protected String storeNameFromContext​(org.snmp4j.smi.OctetString context)
      Return a string store name for the provided SNMPv3 context.
      void unregisterChangeListenersWithServer​(org.snmp4j.agent.MOServer moServer)
      Removes a former registration of this object as MOChangeListener on all RandomAccessManagedObject instances in the provided MOServer.
    • 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.
      • MOXodusPersistence

        public MOXodusPersistence​(org.snmp4j.agent.MOServer[] moServers,
                                  jetbrains.exodus.env.Environment environment,
                                  MOXodusPersistence.SavingStrategy savingStrategy,
                                  org.snmp4j.agent.MOScopeComparator moScopeComparator)
        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.
        moScopeComparator - defines the order in which ManagedObjects are stored and restored from persistent storage. If null, the MOScopeComparator is used that sorts the registered managed objects by their lower bound OID in ascending order.
        Since:
        3.5.0
    • Method Detail

      • isIgnoreChangeListenerEvents

        public boolean isIgnoreChangeListenerEvents​()
        Check whether change listener events are actually suppressed (i.e. ignored) or not.
        Returns:
        true if change listener events will be ignored.
      • 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​()
        Gets the Xodus Environment used by this persistent probvider.
        Returns:
        a Environment.
      • 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

        public void load​(org.snmp4j.agent.io.ImportMode importMode,
                         org.snmp4j.agent.mo.MOPriorityProvider priorityProvider)
        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. Use setMoScopeComparator(MOScopeComparator) to modify the order in which ManagedObjects are loaded. Since version 3.5.0, objects are loaded in the order defined by the MOPriorityProvider given in order to facilitate loading and especially initialization of ManagedObjects that augment or extend base tables or depend on each other. For each context, a load order defined by the content of single boot ManagedObject can be defined. In most cases, a single order defined in the default (null) context is sufficient.
        Parameters:
        importMode - controls how existing data is used or not used during import.
        priorityProvider - if not null, it provides the order for loading and initializing managed objects by MOPriorityProvider.getPriorityMap(OctetString).
      • runSyncOnBootMO

        protected org.snmp4j.agent.ManagedObject<?> runSyncOnBootMO​(jetbrains.exodus.env.Transaction txn,
                                                                    org.snmp4j.agent.MOServer moServer,
                                                                    Map<org.snmp4j.smi.OctetString,jetbrains.exodus.env.Store> stores,
                                                                    org.snmp4j.agent.io.ImportMode importMode,
                                                                    org.snmp4j.agent.mo.MOPriorityProvider priorityProvider,
                                                                    org.snmp4j.smi.OctetString context)
        Run synchronisation on the boot ManagedObject (i.e. the ManagedObject restored before any other.
        Parameters:
        txn - the Transaction.
        moServer - the MOServer.
        stores - the stores containing the persistent data.
        importMode - the ImportMode to be used.
        priorityProvider - the MOPriorityProvider that defines the restore priorities.
        context - the context to restore
        Returns:
        the boot ManagedObject.
      • createStore

        @NotNull
        protected jetbrains.exodus.env.Store createStore​(jetbrains.exodus.env.Transaction txn,
                                                         org.snmp4j.smi.OctetString context)
        Ceates a Store for a context.
        Parameters:
        txn - the Transaction.
        context - the context.
        Returns:
        a new opened Store;
      • 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​()
        Get the associated MOServers.
        Returns:
        an array of MOServer instances.
      • getMoScopeComparator

        public org.snmp4j.agent.MOScopeComparator getMoScopeComparator​()
        Gets the MOScopeComparator that defines the default order in which ManagedObjects are stored and restored from persistent storage (unless the parameter MOPriorityProvider is used).
        Returns:
        a MOScopeComparator instance.
      • setMoScopeComparator

        public void setMoScopeComparator​(org.snmp4j.agent.MOScopeComparator moScopeComparator)
        Sets the MOScopeComparator and by this defines the default order in which ManagedObjects are stored and restored from persistent storage as long as parameter MOPriorityProvider of save(MOPriorityProvider) and load(ImportMode, MOPriorityProvider) are not used. If set to null, the MOScopeComparator is used that sorts the registered managed objects by their lower bound OID in ascending order.
        Parameters:
        moScopeComparator - defines the order in which ManagedObjects are stored and restored from persistent storage. If null, the MOScopeComparator is used that sorts the registered managed objects by their lower bound OID in ascending order.
      • 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)
        Run synchronisation between in memory data and on disk data.
        Parameters:
        stores - the context stores.
        txn - the Transaction.
        importMode - the import mode to use.
        moIterator - the object iterator over the ManagedObjects to be synchronized.
      • decodeInstanceData

        protected List<org.snmp4j.smi.VariableBinding> decodeInstanceData​(jetbrains.exodus.ByteIterable rawData)
        Decode BER instance data from raw byte stream.
        Parameters:
        rawData - the BER encoded data.
        Returns:
        the decoded list of VariableBindings.
      • encodeInstanceData

        protected byte[] encodeInstanceData​(List<org.snmp4j.smi.VariableBinding> vbs)
        Encode instance data from a list of VariableBindings.
        Parameters:
        vbs - a list of VariableBindings.
        Returns:
        a BER encoded byte array.
      • decodeVariableBinding

        protected org.snmp4j.smi.VariableBinding decodeVariableBinding​(org.snmp4j.asn1.BERInputStream inputStream)
                                                                throws IOException
        Decode a VariableBinding from an BERInputStream.
        Parameters:
        inputStream - the BERInputStream
        Returns:
        the decoded VariableBinding.
        Throws:
        IOException - if BER encoding is wrong.
      • encodeVariableBinding

        protected void encodeVariableBinding​(org.snmp4j.smi.VariableBinding vb,
                                             org.snmp4j.asn1.BEROutputStream outputStream)
                                      throws IOException
        Encode a VariableBinding to a BEROutputStream.
        Parameters:
        vb - a VariableBinding.
        outputStream - a BEROutputStream.
        Throws:
        IOException - on a buffer overflow.
      • getKey

        protected jetbrains.exodus.ByteIterable getKey​(org.snmp4j.smi.OID oid,
                                                       org.snmp4j.smi.OID instanceID)
        Gets the key for an OID and instance ID.
        Parameters:
        oid - a OID.
        instanceID - an instance ID.
        Returns:
        a byte stream encoded unique key.
      • getKeyOid

        protected org.snmp4j.smi.OID getKeyOid​(jetbrains.exodus.ByteIterable key)
        Gets the OID of a key.
        Parameters:
        key - a byte stream containing a key.
        Returns:
        the OID portion of the key.
      • save

        public void save​(org.snmp4j.agent.mo.MOPriorityProvider priorityProvider)
        Saves the data of the MOServers associated with this instance to persistent storage depending on the currently configured MOXodusPersistence.SavingStrategy. If that strategy is MOXodusPersistence.SavingStrategy.onChangeEventsOnly, calling this method will have no effect, except that it sets setIgnoreChangeListenerEvents(boolean) to false in any case. Use setMoScopeComparator(MOScopeComparator) to modify the order in which ManagedObjects are stored. Since version 3.5.0, objects are saved in the order defined by the MOPriorityProvider given in order to facilitate saving of ManagedObjects that augment or extend base tables or depend on each other.
        Parameters:
        priorityProvider - if not null, it provides the order for saving the managed objects by MOPriorityProvider.getPriorityMap(OctetString).
      • encodeIndexOID

        public static void encodeIndexOID​(OutputStream os,
                                          byte type,
                                          int[] oid)
                                   throws IOException
        Encodes an index OID.
        Parameters:
        os - the BEROutputStream to encode to.
        type - the type of the index OID (i.e. OID.getSyntax().
        oid - the OID value to encode.
        Throws:
        IOException - if the output stream throws an IOException.
      • getIndexOIDLength

        public static int getIndexOIDLength​(int[] value)
        Get the index OID length from a index OID raw value.
        Parameters:
        value - the OID raw value (see OID.getValue().
        Returns:
        the length of the index.
      • decodeIndexOID

        public static int[] decodeIndexOID​(org.snmp4j.asn1.BERInputStream is,
                                           org.snmp4j.asn1.BER.MutableByte type)
                                    throws IOException
        Decode a index OID from a BER input stream.
        Parameters:
        is - the BERInputStream containing the OID.
        type - the object type read is returned here.
        Returns:
        the decoded OID.
        Throws:
        IOException - if the encoded is wrong.
      • 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)
        Get the contexts registered with all MOServer for the given ManagedObject.
        Parameters:
        managedObject - the managed object.
        Returns:
        the set of registered contexts, see also MOServer.getRegisteredContexts(ManagedObject).