com.seagate.kinetic.KineticTestSimulator.java Source code

Java tutorial

Introduction

Here is the source code for com.seagate.kinetic.KineticTestSimulator.java

Source

/**
 * Copyright 2013-2015 Seagate Technology LLC.
 *
 * This Source Code Form is subject to the terms of the Mozilla
 * Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at
 * https://mozilla.org/MP:/2.0/.
 * 
 * This program is distributed in the hope that it will be useful,
 * but is provided AS-IS, WITHOUT ANY WARRANTY; including without 
 * the implied warranty of MERCHANTABILITY, NON-INFRINGEMENT or 
 * FITNESS FOR A PARTICULAR PURPOSE. See the Mozilla Public 
 * License for more details.
 *
 * See www.openkinetic.org for more project information
 */
package com.seagate.kinetic;

import org.testng.Assert;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;

import kinetic.client.ClientConfiguration;
import kinetic.client.KineticClient;
import kinetic.client.KineticClientFactory;
import kinetic.client.KineticException;
import kinetic.simulator.KineticSimulator;
import kinetic.simulator.SimulatorConfiguration;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;

import com.leacox.process.FinalizedProcess;
import com.leacox.process.FinalizedProcessBuilder;
import com.seagate.kinetic.client.internal.MessageFactory;
import com.seagate.kinetic.common.lib.KineticMessage;
import com.seagate.kinetic.proto.Kinetic.Command;
import com.seagate.kinetic.simulator.lib.MyLogger;

/**
 * Wrapper around java simulator for use in tests. Handles checking System
 * properties to see if the user wanted to run the tests against the Java
 * simulator or some other external device and starts a server as appropriate
 */
public class KineticTestSimulator {
    private final static Logger LOG = MyLogger.get();
    private final String host;
    private final int port;
    private final KineticSimulator kineticServer;
    private final SimulatorConfiguration javaServerConfiguration;
    private final FinalizedProcess externalKineticServer;

    /**
     *
     * Create test simulator.
     *
     * @param clearExistingDatabase
     *            If clear existing data, set true, if not, set false.
     *
     */
    public KineticTestSimulator(boolean clearExistingDatabase)
            throws IOException, InterruptedException, KineticException {
        this(clearExistingDatabase, new SimulatorConfiguration());
    }

    /**
     *
     * Create test simulator.
     *
     * @param clearExistingDatabase
     *            If clear existing data, set true, if not, set false.
     * @param serverConfiguration
     *            Using different configuration to generate different simulator.
     *
     * @throws KineticException
     *             if any internal error occurred.
     * @throws IOException
     *             if any IO error occurred
     * @throws InterruptedException
     *             if any Interrupt error occurred
     *
     * @see SimulatorConfiguration
     */
    public KineticTestSimulator(boolean clearExistingDatabase, SimulatorConfiguration serverConfiguration)
            throws IOException, InterruptedException, KineticException {
        javaServerConfiguration = serverConfiguration;

        String kineticPath = System.getProperty("KINETIC_PATH");
        String kineticHost = System.getProperty("KINETIC_HOST");

        int requestedPort = Integer.parseInt(System.getProperty("KINETIC_PORT", "8123"));

        if (!Boolean.parseBoolean(System.getProperty("RUN_AGAINST_EXTERNAL"))) {
            port = 8123;
            LOG.fine("Starting java simulator on port " + port);
            host = "localhost";
            serverConfiguration.setPort(port);

            if (clearExistingDatabase) {
                deleteJavaServerAuxilaryData();

                String defaultHome = System.getProperty("user.home") + File.separator + "leafcutter";

                String leafcutterHome = serverConfiguration.getProperty(SimulatorConfiguration.KINETIC_HOME,
                        defaultHome);

                FileUtils.deleteQuietly(new File(leafcutterHome));
            }

            // set nio services thread pool size
            serverConfiguration.setNioServiceBossThreads(1);
            serverConfiguration.setNioServiceWorkerThreads(1);

            kineticServer = new KineticSimulator(serverConfiguration);
            externalKineticServer = null;
        } else if (kineticPath != null) {
            port = requestedPort;
            LOG.fine("Running tests against external simulator at " + kineticPath + " using port " + port);
            host = "localhost";
            kineticServer = null;

            FinalizedProcessBuilder finalizedProcessBuilder = new FinalizedProcessBuilder("killall", "-9",
                    "kineticd");
            finalizedProcessBuilder.start().waitFor(10 * 1000);
            Thread.sleep(500);

            // Since the cluster version is checked before performing an ISE we
            // need to manually remove
            // the file used to store the cluster version
            if (clearExistingDatabase) {
                final String workingDirectory = FilenameUtils.getFullPath(kineticPath);
                final String clusterStorePath = FilenameUtils.concat(workingDirectory, "cluster_version");
                FileUtils.deleteQuietly(new File(clusterStorePath));
            }

            finalizedProcessBuilder = new FinalizedProcessBuilder(kineticPath);
            finalizedProcessBuilder.directory(new File("."));
            finalizedProcessBuilder.gobbleStreamsWithLogging(true);

            externalKineticServer = finalizedProcessBuilder.start();
            waitForServerReady();
        } else {
            host = kineticHost;
            port = requestedPort;
            LOG.fine("Running tests against " + host + ":" + port);

            kineticServer = null;
            externalKineticServer = null;
        }

        if (clearExistingDatabase) {

            KineticClient kineticClient = buildClient();

            KineticMessage km = MessageFactory.createKineticMessageWithBuilder();
            Command.Builder commandBuillder = (Command.Builder) km.getCommand();

            commandBuillder.getBodyBuilder().getSetupBuilder();

            /**
             * XXX protocol-3.0.0
             */

            //com.seagate.kinetic.proto.Kinetic.Message.Builder builder = com.seagate.kinetic.proto.Kinetic.Message
            //      .newBuilder();
            //builder.getCommandBuilder().getBodyBuilder().getSetupBuilder()
            //.setInstantSecureErase(true);

            commandBuillder.getHeaderBuilder()
                    .setMessageType(com.seagate.kinetic.proto.Kinetic.Command.MessageType.SETUP);

            kineticClient.request(km);
            kineticClient.close();
        }
    }

    /**
     *
     * Sleep enough time for simulator start and close.
     *
     * @throws InterruptedException
     *             If any interrupt error occurred.
     *
     */
    private void waitForServerReady() throws InterruptedException {
        final int pollingIntervalMS = 50;
        final int maxWaitTimeSec = 10;

        long waitStartTime = System.currentTimeMillis();
        float elapsedTimeMS;
        while (true) {
            Thread.sleep(pollingIntervalMS);

            elapsedTimeMS = System.currentTimeMillis() - waitStartTime;
            if (elapsedTimeMS > maxWaitTimeSec * 1000) {
                throw new RuntimeException("Server never became available");
            }
            try {
                KineticClient kineticClient = buildClient();
                kineticClient.noop();
                kineticClient.close();
                break;
            } catch (KineticException e) {
                // Since all exceptions get turned into KineticException we have
                // to manually check the message
                if (e.getMessage().contains("Kinetic Command Exception: ")) {
                    break;
                }
                // Ignore this exception because it probably means that the
                // server isn't ready yet so
                // we'll just take a brief nap and try again in a bit
            }
        }

        LOG.info("Server ready after waiting ms: " + elapsedTimeMS);
    }

    /**
     *
     * Get simulator port info.
     *
     * @return port return port info.
     *
     */
    public int getPort() {
        return port;
    }

    /**
     *
     * close simulator.
     *
     * @throws IOException
     *             if any IO error occurred.
     *
     */
    public void shutdown() throws IOException {
        if (kineticServer != null) {
            LOG.fine("Stopping Java simulator");
            kineticServer.close();
        }

        if (externalKineticServer != null) {
            externalKineticServer.close();
        }
    }

    /**
     *
     * Generate a Kinetic client.
     *
     * @throws KineticException
     *             if any internal error occurred.
     *
     */
    public KineticClient buildClient() throws KineticException {
        return KineticClientFactory.createInstance(buildClientConfig());
    }

    /**
     *
     * Generate a Kinetic client configuration.
     *
     */
    public ClientConfiguration buildClientConfig() {
        ClientConfiguration clientConfig = new ClientConfiguration();
        clientConfig.setHost(host);
        clientConfig.setPort(getPort());

        // nio service threads in pool
        clientConfig.setNioServiceThreads(1);

        return clientConfig;
    }

    /**
     *
     * Clean data after every test.
     *
     */
    public void deleteJavaServerAuxilaryData() {
        String kineticHome = System.getProperty("user.home") + File.separator + "kinetic";
        if (javaServerConfiguration.getProperty(SimulatorConfiguration.KINETIC_HOME) != null) {
            kineticHome = javaServerConfiguration.getProperty(SimulatorConfiguration.KINETIC_HOME);
        }

        // Delete ACLs
        FileUtils.deleteQuietly(new File(kineticHome + File.separator + ".acl"));
        FileUtils.deleteQuietly(new File(kineticHome + File.separator + ".acl.bak"));

        // Delete setup files
        FileUtils.deleteQuietly(new File(kineticHome + File.separator + ".setup"));
        FileUtils.deleteQuietly(new File(kineticHome + File.separator + ".setup.bak"));

        // Delete history files
        try {
            FileUtils.deleteDirectory(new File(kineticHome + File.separator
                    + javaServerConfiguration.getProperty(SimulatorConfiguration.PERSIST_HOME)));
            FileUtils.deleteQuietly(new File(kineticHome + File.separator + ".acl"));
        } catch (IOException e) {
            Assert.fail("delete directory failed" + e.getMessage());
        }
    }
}