Package LiveRejoinConsistency

Source Code of LiveRejoinConsistency.CheckReplicaConsistency$AppConfig

/* This file is part of VoltDB.
* Copyright (C) 2008-2014 VoltDB Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* This is the "checking" part of the master/replica consistency test app
* it relies on a "short circuit" behavior in to obtain the node local data
*/

package LiveRejoinConsistency;

import java.io.IOException;

import org.voltdb.CLIConfig;
import org.voltdb.VoltTable;
import org.voltdb.client.Client;
import org.voltdb.client.ClientConfig;
import org.voltdb.client.ClientFactory;
import org.voltdb.client.ClientResponse;
import org.voltdb.client.NoConnectionsException;
import org.voltdb.client.ProcCallException;

public class CheckReplicaConsistency {

    // validated command line configuration
    final AppConfig config;
    // Reference to the database connection we will use
    final Client client;

    int nPartitions = 0;

    /**
     * Uses included {@link CLIConfig} class to declaratively state command line
     * options with defaults and validation.
     */
    static class AppConfig extends CLIConfig {
        @Option(desc = "Comma separated list of the form server[:port] to connect to.")
        String servers = "localhost";

        @Option(desc = "Rejoining node name or ip.")
        String rejoinnode = "";

        @Option(desc = "User name for connection.")
        String user = "";

        @Option(desc = "Password for connection.")
        String password = "";
    }

    /**
     * Constructor for benchmark instance. Configures VoltDB client and prints
     * configuration.
     *
     * @param config
     *            Parsed & validated CLI options.
     */
    public CheckReplicaConsistency(AppConfig config) {
        this.config = config;
        client = null;
    }

    public long checkAndReturnCounter(String server, Client client, int pid, String tbl)
            throws NoConnectionsException, IOException, ProcCallException {

        ClientResponse r_sp = null;

        // this sp relies on a "short circuit" behavior in voltdb to obtain the node local
        // value of the counter (so we can compare the data stored on different nodes.
        // Therefore, when the counter table is configured REPLICATED, the query
        // must join to a partitioned table in order to obtain similar "short circuit".
        r_sp = client.callProcedure("getCountFrom"+tbl, pid);

        if (r_sp.getStatus() != ClientResponse.SUCCESS) {
            System.err.printf("SP failed %s\n", r_sp.getStatusString());
            throw new RuntimeException();
        }

        System.err.printf("checkAndReturnCounter %s %d %d\n", server, pid,
                r_sp.getResults()[0].fetchRow(0).getLong(0));

        return r_sp.getResults()[0].fetchRow(0).getLong(0);
    }

    public long returnCRC(String server, Client client, int pid, String tbl)
            throws NoConnectionsException, IOException, ProcCallException {

        // this sp relies on a "short circuit" behavior in voltdb to obtain the node local
        // value of the counter (so we can compare the data stored on different nodes.
        // Therefore, when the counter table is configured REPLICATED, the query
        // must join to a partitioned table in order to obtain similar "short circuit".
        ClientResponse r = client.callProcedure("getCRCFrom"+tbl, pid);

        if (r.getStatus() != ClientResponse.SUCCESS) {
            System.err.printf("SP failed %s\n", r.getStatusString());
            throw new RuntimeException();
        }

        System.err.printf("returnCRC %s %d %d\n", server, pid,
                r.getResults()[0].fetchRow(0).getLong(0));

        return r.getResults()[0].fetchRow(0).getLong(0);
    }

    /**
     * Core benchmark code. Connect. Initialize. Run the loop. Cleanup. Print
     * Results.
     *
     * @throws Exception
     *             if anything unexpected happens.
     */
    public void checkForCorrectness(int ptnOrRep) throws Exception {

        // compare state of all nodes
        // we're employing "short circuit" read queries to get the data on the node
        // exit with nonzero if there is an error

        String z = config.servers;
        String servers[] = z.split(",");
        String[] tblSuffix_ = new String[] {"Ptn", "Rep"};
        String sPtnOrRep = tblSuffix_[ptnOrRep];
        int nTables = 0; // used for catalog check

        System.out.printf("Checking data across nodes, case: %s, servers: %s ...\n", sPtnOrRep, z);

        ClientConfig clientConfig = new ClientConfig(config.user, config.password);
        long[] counters = null;
        long[] crcs = null;
        int crcCount = -1;

        for (int iServer = 0; iServer < servers.length; iServer++) {

            String server = servers[iServer];
            Client client = ClientFactory.createClient(clientConfig);

            try { client.createConnection(server); }
            catch (Exception e) {
                System.err.printf("Error connecting to node %d %s\n", iServer,
                        server);
                e.printStackTrace();
                throw new RuntimeException();
            }

            ClientResponse resp = null;

            if (iServer == 0) {
                // get the partition count
                resp = client.callProcedure("@Statistics", "PARTITIONCOUNT", 0);
                if (resp.getStatus() != ClientResponse.SUCCESS) {
                    System.err.printf("Get partition count failed %s\n", resp.getStatusString());
                    throw new RuntimeException();
                }
                VoltTable[] tpc = resp.getResults();
                nPartitions=0;
                while (tpc[0].advanceRow()) {
                    nPartitions = (int) tpc[0].getLong("PARTITION_COUNT");
                }
                System.out.printf("partition count: %d\n", nPartitions);
                if (nPartitions < 2) {
                    System.err.printf("Less than 2 partitions\n", nPartitions);
                    throw new RuntimeException();
                }
                counters = new long[nPartitions];
                crcs = new long[nPartitions];
            }

            if (nPartitions == 0) {
                System.err.println("Zero partitions should not happen");
                throw new RuntimeException();
            }

            // check the catalog by comparing the number of tables
            resp = client.callProcedure("@Statistics", "TABLE", 0);
            int nt = resp.getResults()[0].getRowCount();
            System.out.printf("table count: %d\n", nt);
            if (iServer == 0)
                nTables = nt;
            else {
                if (nTables != nt) {
                    System.err.printf("TEST FAILED Catalog Table count mismatch %d != %d %s %s\n",
                            nTables, nt, server, servers[0]);
                    System.exit(1);
                    //throw new RuntimeException();
                } else {
                    System.out.printf("Catalog test passed\n");
                }
            }

            for (int pid = 0; pid < nPartitions; pid++) {

                // check the data in the counters tables between the nodes. Use local read
                // techniques ie. "short circuit" read.
                try {
                    long counter = checkAndReturnCounter(server, client,
                            pid, sPtnOrRep);
                    if (iServer == 0)
                        counters[pid] = counter;
                    else if (counters[pid] != counter) {
                        System.err.printf("TEST FAILED Node counter datacompare mismatch %d != %d %s %s\n",
                                counter, counters[pid], server, servers[0]);
                        System.exit(1);
                        //throw new RuntimeException();
                    }
                } catch (Exception e) {
                    System.err.printf("Exception received calling checkAndReturnCounter: server: %s pid: %d\n%s\n",
                            server, pid, e.getMessage());
                    e.printStackTrace();
                    throw new RuntimeException();
                }

                // do the same thing to check the like_counters tbls. We already checked their
                // row counts, now, get a crc of the counter columnn values from all rows (using
                // short circuit read techniques) and compare the crc's.
                try {
                    long crc = returnCRC(server, client,
                            pid, sPtnOrRep);
                    if (iServer == 0)
                        crcs[pid] = crc;
                    else if (crcs[pid] != crc) {
                        System.err.printf("TEST FAILED Node crc datacompare mismatch %d != %d %s %s\n",
                                crc, crcs[pid], server, servers[0]);
                        System.exit(1);
                        //throw new RuntimeException();
                    }
                } catch (Exception e) {
                    System.err.printf("Exception received calling returnCRC: server: %s pid: %d\n%s\n",
                            server, pid, e.getMessage());
                    e.printStackTrace();
                    throw new RuntimeException();
                } }

            client.drain();
            client.close();
        }
        System.out.printf("case: %s All nodes of counter identical\n", sPtnOrRep);
    }

    /**
     * Main routine creates a benchmark instance and kicks off the run method.
     *
     * @param args
     *            Command line arguments.
     * @throws Exception
     *             if anything goes wrong.
     * @see {@link AppConfig}
     */
    public static void main(String[] args) throws Exception {
        // create a configuration from the arguments
        AppConfig config = new AppConfig();
        config.parse(CheckReplicaConsistency.class.getName(), args);
        CheckReplicaConsistency benchmark = new CheckReplicaConsistency(config);
        System.out.println("Checking replicated tables...");
        benchmark.checkForCorrectness(1); // replicated scenario
        System.out.println("Checking partitioned tables...");
        benchmark.checkForCorrectness(0); // partitioned scenario
        System.out.println("Normal End of check\n\n");


    }
}
TOP

Related Classes of LiveRejoinConsistency.CheckReplicaConsistency$AppConfig

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.