All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.snmp4j.agent.io.MOServerPersistence Maven / Gradle / Ivy

There is a newer version: 3.8.1
Show newest version
/*_############################################################################
  _## 
  _##  SNMP4J-Agent 3 - MOServerPersistence.java  
  _## 
  _##  Copyright (C) 2005-2018  Frank Fock (SNMP4J.org)
  _##  
  _##  Licensed under the Apache License, Version 2.0 (the "License");
  _##  you may not use this file except in compliance with the License.
  _##  You may obtain a copy of the License at
  _##  
  _##      http://www.apache.org/licenses/LICENSE-2.0
  _##  
  _##  Unless required by applicable law or agreed to in writing, software
  _##  distributed under the License is distributed on an "AS IS" BASIS,
  _##  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  _##  See the License for the specific language governing permissions and
  _##  limitations under the License.
  _##  
  _##########################################################################*/


package org.snmp4j.agent.io;

import org.snmp4j.agent.request.SubRequest;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;

import java.io.IOException;
import java.util.*;

import org.snmp4j.agent.ManagedObject;

import org.snmp4j.agent.SerializableManagedObject;

import java.util.Map.Entry;

import org.snmp4j.agent.MOScope;
import org.snmp4j.agent.MOContextScope;
import org.snmp4j.log.LogFactory;
import org.snmp4j.log.LogAdapter;
import org.snmp4j.agent.MOServer;

/**
 * The {@code MOServerPersistence} provides persistence operations
 * to load and save serialized MIB data.
 *
 * @author Frank Fock
 * @version 1.4
 */
public class MOServerPersistence {

    private static final LogAdapter logger =
            LogFactory.getLogger(MOServerPersistence.class);

    private MOServer[] servers;

    public MOServerPersistence(MOServer server) {
        this(new MOServer[]{server});
    }

    public MOServerPersistence(MOServer[] moServers) {
        this.servers = moServers;
    }

    private HashMap>> buildCache() {
        HashMap>> serializableMO = new HashMap<>();
        serializableMO.clear();
        for (MOServer server : servers) {
            for (Iterator>> it = server.iterator(); it.hasNext();) {
                Entry> entry = it.next();
                MOScope scope = entry.getKey();
                ManagedObject value = entry.getValue();
                if ((value instanceof SerializableManagedObject) &&
                        (!((SerializableManagedObject) value).isVolatile())) {
                    OctetString context = null;
                    if (scope instanceof MOContextScope) {
                        context = ((MOContextScope) scope).getContext();
                    }
                    LinkedHashMap> objects =
                            serializableMO.computeIfAbsent(context, k -> new LinkedHashMap<>());
                    objects.put(((SerializableManagedObject) value).getID(), (SerializableManagedObject) value);
                }
            }
        }
        return serializableMO;
    }

    public synchronized void loadData(MOInput input) throws IOException {
        HashMap>> serializableMO = buildCache();
        // load context independent data
        LinkedHashMap> mos = serializableMO.get(null);
        if (mos != null) {
            readData(input, mos);
        } else {
            Sequence seq = input.readSequence();
            for (int i = 0; i < seq.getSize(); i++) {
                MOInfo mo = input.readManagedObject();
                input.skipManagedObject(mo);
            }
        }
        // load contexts
        Sequence contextSequence = input.readSequence();
        if (contextSequence != null) {
            for (int i = 0; i < contextSequence.getSize(); i++) {
                Context context = input.readContext();
                boolean skip = true;
//      MOServer server = null;
                for (int s = 0; (skip) && (s < servers.length); s++) {
                    if (servers[s].isContextSupported(context.getContext())) {
                        skip = false;
//          server = servers[s];
                    }
                }
                if (skip) {
                    logger.warn("Context '" + context.getContext() +
                            "' is no longer supported by agent");
                    input.skipContext(context);
                    continue;
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Loading data for context '" + context.getContext() +
                            "'");
                }
                mos = serializableMO.get(context.getContext());
                if (mos == null) {
                    input.skipContext(context);
                    continue;
                }
                readData(input, mos);
                input.skipContext(context);
            }
        }
    }

    private static void readData(MOInput input, LinkedHashMap> mos)
            throws IOException {
        Sequence moGroup = input.readSequence();
        if (moGroup != null) {
            for (int j = 0; j < moGroup.getSize(); j++) {
                MOInfo moid = input.readManagedObject();
                if (logger.isDebugEnabled()) {
                    logger.debug("Looking up object " + moid.getOID());
                }
                SerializableManagedObject mo = mos.get(moid.getOID());
                if (mo != null) {
                    if (logger.isDebugEnabled()) {
                        logger.debug("Loading data for object " + moid.getOID());
                    }
                    mo.load(input);
                }
                input.skipManagedObject(moid);
            }
        }
    }

    /**
     * Saves the serializable data of the associated servers to the given
     * {@link MOOutput}. This method can be called while the registrations
     * of the {@link MOServer}s are changed, because {@link MOServer#iterator()}
     * is synchronized and returns a copy tree of the registered objects.
     *
     * @param output
     *         a {@code MOOutput} instance to store the data.
     *
     * @throws IOException
     *         if the output stream cannot be written.
     */
    public synchronized void saveData(MOOutput output) throws IOException {
        HashMap>> serializableMO = buildCache();
        // write context independent data
        LinkedHashMap> mos = serializableMO.get(null);
        if (logger.isDebugEnabled()) {
            logger.debug("Trying to write MIB data for all contexts");
        }
        if (mos != null) {
            writeData(output, null, mos);
        } else {
            output.writeSequence(new Sequence(0));
        }
        Set contextSet = new HashSet();
        for (MOServer server : servers) {
            contextSet.addAll(Arrays.asList(server.getContexts()));
        }
        OctetString[] contexts = contextSet.toArray(new OctetString[0]);
        output.writeSequence(new Sequence(contexts.length));
        for (OctetString context : contexts) {
            Context c = new Context(context);
            output.writeContextBegin(c);
            if (logger.isDebugEnabled()) {
                logger.debug("Trying to write MIB data for context '" + c.getContext() + "'");
            }
            mos = serializableMO.get(c.getContext());
            if (mos != null) {
                writeData(output, c, mos);
            }
            output.writeContextEnd(c);
        }
    }

    private static void writeData(MOOutput output, Context c,
                                  LinkedHashMap> mos)
            throws IOException {
        if (logger.isDebugEnabled()) {
            if (c == null) {
                logger.debug("Writing " + mos.size() + " context independent managed objects");
            } else {
                logger.debug("Writing " + mos.size() + " managed objects for context '" + c.getContext() + "'");
            }
        }
        output.writeSequence(new Sequence(mos.size()));
        for (SerializableManagedObject mo : mos.values()) {
            MOInfo moInfo = new MOInfo(mo.getID());
            output.writeManagedObjectBegin(moInfo);
            mo.save(output);
            output.writeManagedObjectEnd(moInfo);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy