Class MOXodusPersistence

java.lang.Object
org.snmp4j.agent.db.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 a 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
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    protected static class 
    A parsed representation of an algorithm identifier as accepted by setDefaultEncryptionAlgorithm(String).
    static enum 
    The MOXodusPersistence.SavingStrategy defines how and when persistent data is saved.
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final String
    The default encryption algorithm identifier used by MOXodusPersistence for protecting SecretOctetString values stored to disk.
  • Constructor Summary

    Constructors
    Constructor
    Description
    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.
    MOXodusPersistence(org.snmp4j.agent.MOServer[] moServers, jetbrains.exodus.env.Environment environment, char[] masterPassword)
    Creates a new MOXodusPersistence from an array of MOServer instances, an Xodus Environment, and a master password used to encrypt every SecretOctetString value before it is written to persistent storage.
    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.
    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.
    MOXodusPersistence(org.snmp4j.agent.MOServer[] moServers, jetbrains.exodus.env.Environment environment, MOXodusPersistence.SavingStrategy savingStrategy, org.snmp4j.agent.MOScopeComparator moScopeComparator, char[] masterPassword)
    Creates a new MOXodusPersistence with explicit MOXodusPersistence.SavingStrategy, comparator and master password.
  • Method Summary

    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.
    protected org.snmp4j.smi.Variable
    decodeEncryptedSecretOctetString(org.snmp4j.asn1.BERInputStream inputStream)
    Decodes a BER SEQUENCE that wraps an encrypted SecretOctetString and returns the decrypted value as SecretOctetString.
    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.
    protected SecretKey
    deriveKey(char[] password, byte[] salt, MOXodusPersistence.EncryptionSpec spec)
    Derives an AES SecretKey from password and salt using the KDF named in spec.
    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 void
    encodeVariableBinding(org.snmp4j.smi.VariableBinding vb, org.snmp4j.asn1.BEROutputStream outputStream, byte[] preEncodedVariable)
    Encode a VariableBinding where the Variable part may already be available as a pre-computed BER byte sequence.
    protected byte[]
    encryptSecretToBerSequence(org.snmp4j.security.SecretOctetString secret)
    Encrypts a SecretOctetString value and returns the BER-encoded SEQUENCE that replaces the variable on the wire.
    protected Set<org.snmp4j.smi.OctetString>
    getContexts(org.snmp4j.agent.ManagedObject<?> managedObject)
    Get the contexts registered with all MOServer for the given ManagedObject.
    Returns the encryption algorithm identifier used to protect SecretOctetString values that are newly written to persistent storage.
    jetbrains.exodus.env.Environment
    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
    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[]
    Get the associated MOServers.
    Map<org.snmp4j.smi.OID, Boolean>
    Gets the current exception list for keeping RandomAccessManagedObjects persistent regardless their RandomAccessManagedObject.isVolatile() value or not.
    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
    Return true if the registerChangeListenersWithServer(MOServer) for any server, but unregisterChangeListenersWithServer(MOServer) has not been called yet.
    boolean
    Returns true if a master password is configured and SecretOctetString values will therefore be encrypted on save and decrypted on load.
    boolean
    Check whether change listener events are actually suppressed (i.e. ignored) or not.
    boolean
    Returns the flag controlling how encrypted secrets are handled when loading data without a master password set.
    void
    load(org.snmp4j.agent.io.ImportMode importMode)
    Loads the contents of all managed objects using the specified import mode and the default load order.
    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
    load(org.snmp4j.agent.io.ImportMode importMode, org.snmp4j.agent.mo.MOPriorityProvider priorityProvider, boolean includeVolatile)
    Load the contents of all RandomAccessManagedObjects using RandomAccessManagedObject.importInstance(OID, List, ImportMode) calls.
    Parses a MOXodusPersistence encryption algorithm identifier into a structured MOXodusPersistence.EncryptionSpec.
    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, boolean includeVolatile)
    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. the ManagedObject restored before any other.
    void
    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
    saveFullDump(org.snmp4j.agent.mo.MOPriorityProvider priorityProvider, boolean includeVolatile)
    Saves the data of the MOServers associated with this instance to persistent storage independent of the currently set MOXodusPersistence.SavingStrategy.
    void
    setDefaultEncryptionAlgorithm(String defaultEncryptionAlgorithm)
    Sets the encryption algorithm identifier used to protect SecretOctetString values that are subsequently written to persistent storage.
    void
    setIgnoreChangeListenerEvents(boolean ignoreChangeListenerEvents)
    Defines whether MOChangeEvents should be ignored or not.
    void
    setIgnoreEncryptedDataWithoutPassword(boolean ignoreEncryptedDataWithoutPassword)
    Controls how the persistence loader reacts when it encounters an encrypted SecretOctetString but no master password has been configured.
    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
    setPersistenceExceptionList(Map<org.snmp4j.smi.OID, Boolean> persistenceExceptionList)
    Sets the current exception list for keeping RandomAccessManagedObjects persistent regardless their RandomAccessManagedObject.isVolatile() value or not.
    void
    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.

    Methods inherited from class Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • DEFAULT_ENCRYPTION_ALGORITHM

      public static final String DEFAULT_ENCRYPTION_ALGORITHM
      The default encryption algorithm identifier used by MOXodusPersistence for protecting SecretOctetString values stored to disk. The format is:
        <KDF>:<iterations>:<cipherTransformation>:<keyBits>
      
      The default uses PBKDF2 with HMAC-SHA-256 (600.000 iterations as recommended by OWASP) for key derivation and AES in GCM mode with a 256-bit key for authenticated encryption.
      Since:
      3.8.0
      See Also:
  • Constructor Details

    • 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
    • MOXodusPersistence

      public MOXodusPersistence(org.snmp4j.agent.MOServer[] moServers, jetbrains.exodus.env.Environment environment, char[] masterPassword)
      Creates a new MOXodusPersistence from an array of MOServer instances, an Xodus Environment, and a master password used to encrypt every SecretOctetString value before it is written to persistent storage. The agent's data is restored using the same master password to decrypt those values again when load(ImportMode) (or one of its overloads) is invoked.

      Existing constructors of this class create instances without encryption; passing a non-null master password is the only way to activate encryption. The default encryption algorithm is DEFAULT_ENCRYPTION_ALGORITHM and can be changed via setDefaultEncryptionAlgorithm(String) for newly written data. Already stored secrets carry their own algorithm identifier and can be decrypted independently of the current default.

      Parameters:
      moServers - the ManagedObject servers of the agent to be supported with persistent storage capabilities.
      environment - the Xodus environment that actually holds the persistent data.
      masterPassword - the master password used to derive the symmetric key that protects SecretOctetString values. The array is defensively copied. Pass null to disable encryption (in which case you should use one of the password-less constructors instead).
      Since:
      3.8.0
    • MOXodusPersistence

      public MOXodusPersistence(org.snmp4j.agent.MOServer[] moServers, jetbrains.exodus.env.Environment environment, MOXodusPersistence.SavingStrategy savingStrategy, org.snmp4j.agent.MOScopeComparator moScopeComparator, char[] masterPassword)
      Creates a new MOXodusPersistence with explicit MOXodusPersistence.SavingStrategy, comparator and master password. See MOXodusPersistence(MOServer[], Environment, char[]) for the encryption semantics.
      Parameters:
      moServers - the ManagedObject servers of the agent to be supported with persistent storage capabilities.
      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, a default MOScopeComparator is used.
      masterPassword - the master password used to derive the symmetric key that protects SecretOctetString values. The array is defensively copied. Pass null to disable encryption.
      Since:
      3.8.0
  • Method Details

    • getSavingStrategy

      public MOXodusPersistence.SavingStrategy getSavingStrategy()
      Gets the saving strategy as defined by MOXodusPersistence.SavingStrategy.
      Returns:
      the current managed object saving strategy.
    • setSavingStrategy

      public void setSavingStrategy(MOXodusPersistence.SavingStrategy savingStrategy)
      Sets the saving strategy for this persistence provider as defined by MOXodusPersistence.SavingStrategy.
      Parameters:
      savingStrategy - the new managed object saving strategy.
    • 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.
    • isEncryptionEnabled

      public boolean isEncryptionEnabled()
      Returns true if a master password is configured and SecretOctetString values will therefore be encrypted on save and decrypted on load.
      Returns:
      whether encryption of SecretOctetString values is active.
      Since:
      3.8.0
    • getDefaultEncryptionAlgorithm

      public String getDefaultEncryptionAlgorithm()
      Returns the encryption algorithm identifier used to protect SecretOctetString values that are newly written to persistent storage. Values that have already been stored carry their own algorithm identifier and remain decryptable independent of this setting.
      Returns:
      an algorithm identifier of the form <KDF>:<iterations>:<cipherTransformation>:<keyBits>, by default DEFAULT_ENCRYPTION_ALGORITHM.
      Since:
      3.8.0
    • setDefaultEncryptionAlgorithm

      public void setDefaultEncryptionAlgorithm(String defaultEncryptionAlgorithm)
      Sets the encryption algorithm identifier used to protect SecretOctetString values that are subsequently written to persistent storage. The value must be parseable by parseEncryptionAlgorithm(String).
      Parameters:
      defaultEncryptionAlgorithm - a non-null algorithm identifier of the form <KDF>:<iterations>:<cipherTransformation>:<keyBits>.
      Since:
      3.8.0
    • isIgnoreEncryptedDataWithoutPassword

      public boolean isIgnoreEncryptedDataWithoutPassword()
      Returns the flag controlling how encrypted secrets are handled when loading data without a master password set. See setIgnoreEncryptedDataWithoutPassword(boolean) for details.
      Returns:
      true if encrypted secrets are passed through as opaque SecretOctetStrings when no master password is set; false (the default) if loading aborts in that situation.
      Since:
      3.8.0
    • setIgnoreEncryptedDataWithoutPassword

      public void setIgnoreEncryptedDataWithoutPassword(boolean ignoreEncryptedDataWithoutPassword)
      Controls how the persistence loader reacts when it encounters an encrypted SecretOctetString but no master password has been configured. If true, the raw BER encoded sequence representing the encrypted value is wrapped into a SecretOctetString and returned to the agent as-is — allowing data to be re-saved untouched when the password is unknown. If false (the default), the loader logs a fatal error and aborts with a RuntimeException.
      Parameters:
      ignoreEncryptedDataWithoutPassword - true to suppress the fatal error and return the encrypted bytes as a SecretOctetString.
      Since:
      3.8.0
    • getEnvironment

      public jetbrains.exodus.env.Environment getEnvironment()
      Gets the Xodus Environment used by this persistent probvider.
      Returns:
      a Environment.
    • isContinuousChangeListening

      public boolean isContinuousChangeListening()
      Return true if the registerChangeListenersWithServer(MOServer) for any server, but unregisterChangeListenersWithServer(MOServer) has not been called yet.
      Returns:
      true if the registerChangeListenersWithServer(MOServer) for any server.
    • 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)
      Loads the contents of all managed objects using the specified import mode and the default load order. This is a convenience method that calls load(ImportMode, MOPriorityProvider) with a null priority provider.
      Parameters:
      importMode - controls how existing data is used or not used during import.
    • 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).
    • load

      public void load(org.snmp4j.agent.io.ImportMode importMode, org.snmp4j.agent.mo.MOPriorityProvider priorityProvider, boolean includeVolatile)
      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).
      includeVolatile - if true, RandomAccessManagedObjects with RandomAccessManagedObject.isVolatile() true will be saved too, otherwise those objects will not be saved.
      Since:
      3.6.0
    • 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

      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, boolean includeVolatile)
      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.
      includeVolatile - if true, RandomAccessManagedObjects with RandomAccessManagedObject.isVolatile() true will be saved too, otherwise those objects will not be saved.
    • 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. If a master password has been configured (see MOXodusPersistence(MOServer[], Environment, char[])) and the value of vb is a SecretOctetString, the value is encrypted before being written. The encrypted representation replaces the original Variable with a BER BER.SEQUENCE consisting of three OCTET STRINGs (algorithm identifier, ciphertext with IV prefix, KDF salt).
      Parameters:
      vb - a VariableBinding.
      outputStream - a BEROutputStream.
      Throws:
      IOException - on a buffer overflow.
    • encodeVariableBinding

      protected void encodeVariableBinding(org.snmp4j.smi.VariableBinding vb, org.snmp4j.asn1.BEROutputStream outputStream, byte[] preEncodedVariable) throws IOException
      Encode a VariableBinding where the Variable part may already be available as a pre-computed BER byte sequence. This overload is used internally to avoid encrypting twice (once during size calculation, once during the actual write).
      Parameters:
      vb - the VariableBinding.
      outputStream - the target BEROutputStream.
      preEncodedVariable - if non-null, the bytes are written verbatim in place of vb.getVariable().encodeBER(...); if null, the variable encodes itself.
      Throws:
      IOException - on a buffer overflow.
      Since:
      3.8.0
    • 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()
      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.
    • 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).
    • saveFullDump

      public void saveFullDump(org.snmp4j.agent.mo.MOPriorityProvider priorityProvider, boolean includeVolatile)
      Saves the data of the MOServers associated with this instance to persistent storage independent of the currently set MOXodusPersistence.SavingStrategy. In other words, any non-volatile ManagedObject will be saved to persistent storage.
      Parameters:
      priorityProvider - if not null, it provides the order for saving the managed objects by MOPriorityProvider.getPriorityMap(OctetString).
      includeVolatile - if true, RandomAccessManagedObjects with RandomAccessManagedObject.isVolatile() true will be saved too, otherwise those objects will not be saved.
      Since:
      3.6.0
    • 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.
    • getPersistenceExceptionList

      public Map<org.snmp4j.smi.OID, Boolean> getPersistenceExceptionList()
      Gets the current exception list for keeping RandomAccessManagedObjects persistent regardless their RandomAccessManagedObject.isVolatile() value or not. A RandomAccessManagedObject is kept exceptionally persistent if its OID is key of the returned list and its value is true. If the value is false, the corresponding RandomAccessManagedObject will not be stored/restored even if it is non-volatile (i.e., RandomAccessManagedObject.isVolatile() returns false).
      Returns:
      the exception list. If null is returned, there are no exceptions defined/active (same effect as an empty exception list).
      Since:
      3.6.0
    • setPersistenceExceptionList

      public void setPersistenceExceptionList(Map<org.snmp4j.smi.OID, Boolean> persistenceExceptionList)
      Sets the current exception list for keeping RandomAccessManagedObjects persistent regardless their RandomAccessManagedObject.isVolatile() value or not. A RandomAccessManagedObject is kept exceptionally persistent if its OID is key of the provided list and its value is true. If the value is false, the corresponding RandomAccessManagedObject will not be stored/restored even if it is non-volatile (i.e., RandomAccessManagedObject.isVolatile() returns false). For RandomAccessManagedObjects with a rang eof OIDs, the lower bound of its MOScope has to be provided.
      Parameters:
      persistenceExceptionList - the exception list. If null is provided, there are no exceptions defined/active (same effect as an empty exception list).
      Since:
      3.6.0
    • 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).
    • encryptSecretToBerSequence

      protected byte[] encryptSecretToBerSequence(org.snmp4j.security.SecretOctetString secret)
      Encrypts a SecretOctetString value and returns the BER-encoded SEQUENCE that replaces the variable on the wire. The returned bytes form a complete BER object (tag + length + content) with three OCTET STRING children: the algorithm identifier, the ciphertext (with the cipher IV prefixed), and the random PBKDF2 salt.
      Parameters:
      secret - the value to encrypt. Must not be null.
      Returns:
      a BER-encoded SEQUENCE replacing the Variable portion of the VariableBinding.
      Since:
      3.8.0
    • decodeEncryptedSecretOctetString

      protected org.snmp4j.smi.Variable decodeEncryptedSecretOctetString(org.snmp4j.asn1.BERInputStream inputStream) throws IOException
      Decodes a BER SEQUENCE that wraps an encrypted SecretOctetString and returns the decrypted value as SecretOctetString. The input stream must be positioned at the SEQUENCE tag.

      If no master password is configured, behaviour depends on isIgnoreEncryptedDataWithoutPassword(): when true, the raw BER octet stream of the sequence (including header) is returned wrapped in a SecretOctetString so that the data can be passed through unchanged. When false, a fatal log message is emitted and a RuntimeException is thrown to abort the load.

      Parameters:
      inputStream - a BERInputStream positioned at the SEQUENCE tag of an encrypted secret.
      Returns:
      the decrypted SecretOctetString, or the opaque raw bytes if no password is set and the ignore-flag has been activated.
      Throws:
      IOException - if the input stream is malformed or decryption fails.
      Since:
      3.8.0
    • deriveKey

      protected SecretKey deriveKey(char[] password, byte[] salt, MOXodusPersistence.EncryptionSpec spec) throws GeneralSecurityException
      Derives an AES SecretKey from password and salt using the KDF named in spec. The returned key is wrapped in a SecretKeySpec that uses the cipher algorithm (the part before the first "/" in the transformation string) so that it can be passed to Cipher.init(int, java.security.Key, java.security.spec.AlgorithmParameterSpec).
      Parameters:
      password - the master password (defensively cleared inside the PBE key spec).
      salt - the per-value random salt.
      spec - the parsed encryption algorithm specification.
      Returns:
      a SecretKey usable with the configured cipher.
      Throws:
      GeneralSecurityException - if the JCE provider does not support the requested KDF or key size.
      Since:
      3.8.0
    • parseEncryptionAlgorithm

      protected MOXodusPersistence.EncryptionSpec parseEncryptionAlgorithm(String id)
      Parses a MOXodusPersistence encryption algorithm identifier into a structured MOXodusPersistence.EncryptionSpec. The expected format is <KDF>:<iterations>:<cipherTransformation>:<keyBits>, e.g. PBKDF2WithHmacSHA256:600000:AES/GCM/NoPadding:256.
      Parameters:
      id - the algorithm identifier.
      Returns:
      the parsed MOXodusPersistence.EncryptionSpec.
      Throws:
      IllegalArgumentException - if id does not have the expected format or contains invalid values.
      Since:
      3.8.0