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)  
      static int[] decodeIndexOID​(org.snmp4j.asn1.BERInputStream is, org.snmp4j.asn1.BER.MutableByte type)  
      protected List<org.snmp4j.smi.VariableBinding> decodeInstanceData​(jetbrains.exodus.ByteIterable rawData)  
      protected org.snmp4j.smi.VariableBinding decodeVariableBinding​(org.snmp4j.asn1.BERInputStream inputStream)  
      static void encodeIndexOID​(OutputStream os, byte type, int[] oid)  
      protected byte[] encodeInstanceData​(List<org.snmp4j.smi.VariableBinding> vbs)  
      protected void encodeVariableBinding​(org.snmp4j.smi.VariableBinding vb, org.snmp4j.asn1.BEROutputStream outputStream)  
      protected Set<org.snmp4j.smi.OctetString> getContexts​(org.snmp4j.agent.ManagedObject managedObject)  
      jetbrains.exodus.env.Environment getEnvironment​()  
      static int getIndexOIDLength​(int[] value)  
      protected jetbrains.exodus.ByteIterable getKey​(org.snmp4j.smi.OID oid, org.snmp4j.smi.OID instanceID)  
      protected org.snmp4j.smi.OID getKeyOid​(jetbrains.exodus.ByteIterable 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​()  
      MOXodusPersistence.SavingStrategy getSavingStrategy​()  
      boolean isContextLoadable​(org.snmp4j.smi.OctetString context)
      Checks if there is already MIB data stored for the specified context.
      boolean isContinuousChangeListening​()  
      boolean isIgnoreChangeListenerEvents​()  
      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)  
      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)  
      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)  
      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​()
      • 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

        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)
      • 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​()
      • 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)
      • 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)
      • 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).
      • 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)