alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (Recovery.java)

This example Java source code file (Recovery.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

exception, file, internalerror, ioexception, object, passed, printstream, recovery, reliablelog, simulated, string, stringbuffer, test, wrote

The Recovery.java Java example source code

/*
 * Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
 * @summary sanity test for log sudden-death and recovery
 * @run ignore Requires special hooks in ReliableLog not yet putback.
 */

/* The ReliableLog uses three filenames and renaming to effect atomic
 * versionFile updates.  First, a newVersionFile (an intention list)
 * is written.  Next, the current versionFile is renamed to an
 * oldVersionFile (an undo list).  Finally, the newVersionFile is
 * renamed to the current versionFile, and the undo list is discarded.
 * If the current version file does not exist on restart, then
 * stability can always be restored by reading the oldVersionFile.
 *
 * This test uses little conditional bombs.  When a switch is flipped
 * in ReliableLog, the code will abort with an InternalError at a
 * particular point.  We then pretend to have come up from scratch and
 * recover from the bombed situation.
 */

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Serializable;
import sun.rmi.log.LogHandler;
import sun.rmi.log.ReliableLog;

//import javasoft.sqe.harness.Status;
//import javasoft.sqe.harness.Test;

public class Recovery
    extends LogHandler
    implements Serializable //, Test
{
    static private final String dir = "./recovery_tmp";

    static public void main (String[] argv)
    {
        Recovery test = new Recovery();
        //Status status = test.run (argv, System.err, System.out);
        //status.exit();
        test.run (argv, System.err, System.out);
    }

    //public Status run (String argv[], PrintStream log, PrintStream out)
    public void run (String argv[], PrintStream lg, PrintStream out)
    {
        try {
            int size;
            int deathpoint;
            for (size = 1; size < 256; size *= 2) {
                for (deathpoint = 0; deathpoint <= 8; deathpoint++) {
                    // Trash the log directory
                    try {
                        (new File(dir,"Version_Number")).delete();
                    } catch (Exception e) {
                    }
                    try {
                        (new File(dir,"New_Version_Number")).delete();
                    } catch (Exception e) {
                    }
                    try {
                        (new File(dir,"Old_Version_Number")).delete();
                    } catch (Exception e) {
                    }

                    Recovery handler = new Recovery();
                    ReliableLog log;
                    if (size == 4 && deathpoint == 6) {
                        Runtime.getRuntime().traceMethodCalls(true);
                    }
                    log = new ReliableLog(dir, handler);
                    if (size == 4 && deathpoint == 6) {
                        Runtime.getRuntime().traceMethodCalls(false);
                    }

                    // Generate a number of updates (size - 1) until failing
                    int i;
                    StringBuffer writ = new StringBuffer();
                    char[] u = new char[1];
                    for (i = 1; i < size; i++) {
                        u[0] = (char)(64 + (i % 26));
                        String update = new String(u);
                        handler.basicUpdate(update);
                        log.update(update, true);
                        writ.append(update);
                    }

                    // Fail
                    String f = ("FALL" + deathpoint);
                    boolean failed_as_desired = false;
                    try {
                        ReliableLog.fallOverPoint = deathpoint;
                        handler.basicUpdate(f);
                        log.update(f, true);
                        log.snapshot(handler);
                    } catch (InternalError e) {
                        if (!e.getMessage().equals(f))
                            throw e; // oops, not ours
                        failed_as_desired = true;
                    } finally {
                        ReliableLog.fallOverPoint = 0;
                        try {
                            log.close();
                        } catch (IOException ign) {
                        }
                    }

                    // deathpoint == 0 means that there is no deathpoint and we are testing
                    // undisastered behaviour.
                    if (!failed_as_desired && deathpoint != 0) {
                        System.err.println ("sun.rmi.log.ReliableLog is not instrumented for" +
                                            " this test; test skipped");
                        return;
                    }

                    // Now try to recover.
                    Recovery laz = new Recovery();
                    ReliableLog carbon = new ReliableLog(dir, laz);
                    Recovery thingy;
                    thingy = (Recovery)carbon.recover();
                    try {
                        carbon.close();
                    } catch (IOException ign) {
                    }

                    // Recovered thingy must be equal to writ or to writ + f, but nothing
                    // else (or in between).
                    String recovered = thingy.contents;
                    String sacr = writ.toString();
                    if (recovered.length() == sacr.length()
                        && recovered.compareTo(sacr) == 0)
                    {
                        lg.println("Passed test " + size + "/" + deathpoint
                                   + ": rolled back to v1");
                    } else if (recovered.length() == (sacr.length() + f.length())
                               && recovered.compareTo(sacr + f) == 0)
                    {
                        lg.println("Passed test " + size + "/" + deathpoint
                                   + ": committed to v2");
                    } else {
                        final String q = "\"";
                        lg.println("Wrote " + sacr.length() + ": " + q + sacr + q);
                        lg.println("Simulated failure during write "
                                   + f.length() + ": " + q + f + q);
                        lg.println("Recovered " + recovered.length() + ": " + q + recovered + q);
                        throw new InternalError("Failed test " + size + "/" + deathpoint
                                   + " (size/deathpoint):");
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace(lg);
            //return (Status.failed
            throw (new RuntimeException
                    ("Exception in sanity test for sun.rmi.log.ReliableLog"));
        }
        //return (Status.passed ("OKAY"));
    }

    private String contents;
    transient private StringBuffer trc = null;

    public Recovery()
    {
        super();
        if (this.contents == null)
            this.contents = "?";
    }

    // implements LogHandler.initialSnapshot()
    public Object initialSnapshot()
        throws Exception
    {
        this.contents = "";
        return (this);
    }

    // implements LogHandler.applyUpdate()
    public Object applyUpdate (Object update, Object state)
        throws Exception
    {
        // basicUpdate appends the string
        ((Recovery)state).basicUpdate ((String)update);
        return (state);
    }

    // an "update" is a short string to append to this.contents (must ignore state)
    public void basicUpdate (String extra)
    {
        this.contents = this.contents + extra;
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java Recovery.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.