Package org.rioproject.monitor.service.persistence

Source Code of org.rioproject.monitor.service.persistence.OpStringLogHandler

/*
* Copyright to the original author or authors.
*
* 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.rioproject.monitor.service.persistence;

import com.sun.jini.reliableLog.LogHandler;
import org.rioproject.monitor.service.OpStringManager;
import org.rioproject.monitor.service.OpStringManagerController;
import org.rioproject.opstring.OperationalString;
import org.rioproject.opstring.OperationalStringException;
import org.rioproject.impl.persistence.SnapshotHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.rmi.MarshalledObject;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;

/**
* Class that manages the persistence details behind saving and restoring
* OperationalStrings
*/
public class OpStringLogHandler extends LogHandler implements SnapshotHandler {
    /**
     * Collection of of recovered Operational Strings to add
     */
    private final Collection<OperationalString> recoveredOpstrings = new ArrayList<OperationalString>();
    /**
     * Collection of of recovered Operational Strings to add
     */
    private final Collection<RecordHolder> updatedOpstrings = new ArrayList<RecordHolder>();
    /**
     * flag to indicate whether OperationalStrings have been recovered
     */
    private boolean opStringsRecovered = false;
    /** Flag to indicate that we are in recover mode */
    private AtomicBoolean inRecovery = new AtomicBoolean(false);
    /** Log File must contain this many records before a snapshot is allowed */
    // TODO - allow this to be a user configurable parameter
    int logToSnapshotThresh = 10;
    OpStringManagerController opStringMangerController;
    SnapshotThread snapshotter;

    /** Log format version */
    static final int LOG_VERSION = 1;

    static Logger logger = LoggerFactory.getLogger(OpStringLogHandler.class.getName());

    void setOpStringMangerController(OpStringManagerController opStringMangerController) {
        this.opStringMangerController = opStringMangerController;
    }

    public boolean inRecovery() {
        return inRecovery.get();
    }

    void setSnapshotter(SnapshotThread snapshotter) {
        this.snapshotter = snapshotter;
    }

    public void snapshot(OutputStream out) throws IOException {
        ObjectOutputStream oostream = new ObjectOutputStream(out);
        oostream.writeUTF(OpStringLogHandler.class.getName());
        oostream.writeInt(LOG_VERSION);
        List<OperationalString> list = new ArrayList<OperationalString>();
        OperationalString[] opStrings = opStringMangerController.getOperationalStrings();
        list.addAll(Arrays.asList(opStrings));
        oostream.writeObject(new MarshalledObject<List<OperationalString>>(list));
        oostream.flush();
    }

    /**
     * Required method implementing the abstract recover() defined in
     * ReliableLog's associated LogHandler class. This callback is invoked
     * from the recover method of ReliableLog.
     */
    @SuppressWarnings("unchecked")
    public void recover(InputStream in) throws Exception {
        inRecovery.set(true);
        ObjectInputStream oistream = new ObjectInputStream(in);
        if (!OpStringLogHandler.class.getName().equals(oistream.readUTF()))
            throw new IOException("Log from wrong implementation");
        if (oistream.readInt() != LOG_VERSION)
            throw new IOException("Wrong log format version");
        MarshalledObject mo = (MarshalledObject) oistream.readObject();
        List<OperationalString> list = (List<OperationalString>) mo.get();
        for (OperationalString opString : list) {
            if (logger.isDebugEnabled())
                logger.debug("Recovered : " + opString.getName());
            //dumpOpString(opString);
            recoveredOpstrings.add(opString);
            opStringsRecovered = true;
        }
    }

    /**
     * Required method implementing the abstract applyUpdate() defined in
     * ReliableLog's associated LogHandler class.
     * <p/>
     * During state recovery, the recover() method defined in the
     * ReliableLog class is invoked. That method invokes the method
     * recoverUpdates() which invokes the method readUpdates(). Both of
     * those methods are defined in ReliableLog. The method readUpdates()
     * retrieves a record from the log file and then invokes this method.
     */
    public void applyUpdate(Object update) throws Exception {
        if (update instanceof MarshalledObject) {
            RecordHolder holder = (RecordHolder) ((MarshalledObject) update).get();
            updatedOpstrings.add(holder);
            opStringsRecovered = true;
        }
    }

    /**
     * Called by <code>PersistentStore</code> after every update to give
     * server a chance to trigger a snapshot <br>
     *
     * @param updateCount Number of updates since last snapshot
     */
    public void updatePerformed(int updateCount) {
        if (updateCount >= logToSnapshotThresh) {
            snapshotter.takeSnapshot();
        }
    }

    /**
     * Delegate snapshot request to PersistentStore
     */
    public void takeSnapshot() {
        snapshotter.takeSnapshot();
    }

    /**
     * Determine if OperationalString objects have been recovered or updated
     *
     * @return boolean <code/true</code> if OperationalString objects have
     *         been recovered or updated, otherwise <code>false</code>
     */
    boolean opStringsRecovered() {
        return (opStringsRecovered);
    }

    /**
     * Process recovered OperationalString objects
     */
    void processRecoveredOpStrings() {
        for (OperationalString opString : recoveredOpstrings) {
            try {
                if (!opStringMangerController.opStringExists(opString.getName())) {
                    Map<String, Throwable> map = new HashMap<String, Throwable>();
                    opStringMangerController.addOperationalString(opString, map, null, null, null);
                    opStringMangerController.dumpOpStringError(map);
                } else {
                    OpStringManager opMgr = opStringMangerController.getOpStringManager(opString.getName());
                    Map map = opMgr.doUpdateOperationalString(opString);
                    opStringMangerController.dumpOpStringError(map);
                }
            } catch (Exception ex) {
                logger.warn("Processing recovered OperationalStrings", ex);
            }
        }
        recoveredOpstrings.clear();
    }

    /**
     * Process updated OperationalString objects
     *
     * @throws org.rioproject.opstring.OperationalStringException
     *          if there are errors processing
     *          the OperationalStrings
     */
    void processUpdatedOpStrings() throws OperationalStringException {
        for (RecordHolder holder : updatedOpstrings) {
            OperationalString opString = holder.getOperationalString();
            try {
                if (holder.getAction() == RecordHolder.MODIFIED) {
                    if (!opStringMangerController.opStringExists(opString.getName())) {
                        Map<String, Throwable> map = new HashMap<String, Throwable>();
                        opStringMangerController.addOperationalString(opString, map, null, null, null);
                        opStringMangerController.dumpOpStringError(map);
                    } else {
                        OpStringManager opMgr = opStringMangerController.getOpStringManager(opString.getName());
                        Map map = opMgr.doUpdateOperationalString(opString);
                        opStringMangerController.dumpOpStringError(map);
                    }
                } /*else {
                    undeploy(opString.getName(), false);
                }*/
            } catch (Exception ex) {
                logger.warn("Processing updated OperationalStrings", ex);
            }
        }
        updatedOpstrings.clear();
    }
}
TOP

Related Classes of org.rioproject.monitor.service.persistence.OpStringLogHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.