org.exfio.weave.client.WeaveClientCLI.java Source code

Java tutorial

Introduction

Here is the source code for org.exfio.weave.client.WeaveClientCLI.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Gerry Healy <nickel_chrome@mac.com>
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     Gerry Healy <nickel_chrome@mac.com> - Initial implementation
 ******************************************************************************/
package org.exfio.weave.client;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.exfio.weave.AccountNotFoundException;
import org.exfio.weave.WeaveException;
import org.exfio.weave.account.WeaveAccount;
import org.exfio.weave.account.WeaveAccountCLI;
import org.exfio.weave.account.fxa.FxAccount;
import org.exfio.weave.account.fxa.FxAccountParams;
import org.exfio.weave.account.legacy.LegacyV5Account;
import org.exfio.weave.account.legacy.LegacyV5AccountParams;
import org.exfio.weave.client.WeaveClient;
import org.exfio.weave.client.WeaveClientFactory.ApiVersion;
import org.exfio.weave.storage.NotFoundException;
import org.exfio.weave.storage.WeaveBasicObject;
import org.exfio.weave.storage.WeaveCollectionInfo;
import org.exfio.weave.util.Log;
import org.exfio.weave.util.OSUtils;

public class WeaveClientCLI {

    public static List<Thread> getThreads() {
        Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
        return Arrays.asList(threadSet.toArray(new Thread[threadSet.size()]));
    }

    //**********************************
    // CLI interface and helper methods
    //**********************************

    public static void printUsage(Options options) {
        System.out.println();
        HelpFormatter formatter = new HelpFormatter();
        formatter.printHelp("weaveclient", options);
    }

    public static void main(String[] args) {

        String accountServer = null;
        String tokenServer = null;
        String username = null;
        String password = null;
        String synckey = null;
        String collection = null;
        String id = null;
        String payload = null;
        boolean delete = false;
        boolean info = false;
        boolean ids = false;
        boolean encrypt = true;
        String loglevel = null;

        WeaveClientFactory.ApiVersion apiVersion = null;

        // Parse commandline arguments
        Options options = new Options();

        options.addOption("h", "help", false, "print this message");

        //Initialiseb account from local storage
        options.addOption("a", "account", true, "load config for account");
        options.addOption("f", "config-file", true, "load config from file");
        options.addOption("p", "password", true, "password");

        //Initialise account from commandline parameters
        options.addOption("v", "api-version", true, "api version (auto|1.1|1.5). Defaults to 1.1");
        options.addOption("s", "account-server", true, "account server URL");
        options.addOption("t", "token-server", true, "token server URL");
        options.addOption("u", "username", true, "username");
        options.addOption("k", "sync-key", true, "sync key");

        //Weave sync storage request parameters
        options.addOption("c", "collection", true, "collection");
        options.addOption("i", "id", true, "object ID");
        options.addOption(null, "plaintext", false, "do not encrypt/decrypt item");
        options.addOption("m", "modify", true,
                "update item with given value in JSONUtils format. Requires -c and -i");
        options.addOption("d", "delete", false, "delete item. Requires -c and -i");
        options.addOption("n", "info", false, "get collection info. Requires -c");
        options.addOption("o", "ids", false, "get collection ids. Requires -c");

        options.addOption("l", "log-level", true, "set log level (trace|debug|info|warn|error)");

        CommandLineParser parser = new GnuParser();
        CommandLine cmd = null;
        try {
            cmd = parser.parse(options, args);
        } catch (ParseException exp) {
            System.err.println("Parsing failed: " + exp.getMessage());
            System.exit(1);
        }

        if (cmd.hasOption('h')) {
            // help
            printUsage(options);
            System.exit(0);
        }

        //Need to set log level BEFORE instansiating Logger
        loglevel = "warn";
        if (cmd.hasOption('l')) {
            loglevel = cmd.getOptionValue('l').toLowerCase();
            if (!loglevel.matches("trace|debug|info|warn|error")) {
                System.err.println("log level must be one of (trace|debug|info|warn|error)");
                System.exit(1);
            }
        }
        Log.init(loglevel);

        //DEBUG only
        //Log.getInstance().warn("Log warn message");
        //Log.getInstance().info("Log info message");
        //Log.getInstance().debug("Log debug message");

        // OS details
        Log.getInstance().debug(String.format("os: %s, distro: %s, hostname: %s, prettyname: %s", OSUtils.getOS(),
                OSUtils.getDistro(), OSUtils.getHostName(), OSUtils.getPrettyName()));

        // Intialise account
        WeaveAccount account = null;

        if (cmd.hasOption('f') || cmd.hasOption('a')) {

            //Get account params from local storage
            File clientConfig = null;
            Properties clientProp = null;

            try {
                if (cmd.hasOption('f')) {
                    clientConfig = new File(cmd.getOptionValue('f'));
                } else if (cmd.hasOption('a')) {
                    clientConfig = WeaveAccountCLI.buildAccountConfigPath(cmd.getOptionValue('a'));
                }

                clientProp = new Properties();
                clientProp.load(new FileInputStream(clientConfig));

            } catch (IOException e) {
                System.err.println(String.format("Couldn't load client config - %s", e.getMessage()));
                System.exit(1);
            } catch (AccountNotFoundException e) {
                System.err.println(String.format("Couldn't load client config - %s", e.getMessage()));
                System.exit(1);
            }

            String apiVersionString = clientProp.getProperty(WeaveAccount.KEY_ACCOUNT_CONFIG_APIVERSION, null);
            if (apiVersionString == null || apiVersionString.isEmpty()) {
                System.err.println("apiversion is a required config parameter");
                System.exit(1);
            }

            apiVersion = WeaveClientFactory.stringToApiVersion(apiVersionString);

            if (apiVersion == WeaveClientFactory.ApiVersion.v1_1) {
                password = cmd.getOptionValue('p');
                if (password == null || password.isEmpty()) {
                    System.err.println("password is a required parameters");
                    System.exit(1);
                }

                try {
                    account = new LegacyV5Account();
                    account.init(clientProp, password);
                } catch (WeaveException e) {
                    System.err
                            .println(String.format("Couldn't initialise Weave Sync account - %s", e.getMessage()));
                    System.exit(1);
                }
            } else if (apiVersion == WeaveClientFactory.ApiVersion.v1_5) {
                password = cmd.getOptionValue('p');
                if (password == null || password.isEmpty()) {
                    System.err.println("password is a required parameters");
                    System.exit(1);
                }

                try {
                    account = new FxAccount();
                    account.init(clientProp, password);
                } catch (WeaveException e) {
                    System.err
                            .println(String.format("Couldn't initialise Weave Sync account - %s", e.getMessage()));
                    System.exit(1);
                }
            } else {
                System.err.println("Storage version not recognised");
                System.exit(1);
            }

            //Update client config file, i.e. new certificate and/or token

            if (clientConfig != null && clientConfig.canWrite()) {
                clientProp = account.accountParamsToProperties(false);

                try {
                    clientProp.store(new FileOutputStream(clientConfig), "");
                } catch (IOException e) {
                    System.err.println(String.format("Couldn't write client config file '%s'",
                            clientConfig.getAbsolutePath()));
                    //System.exit(1);
                }
            }

        } else {

            //Get account params from command line

            //Get storage version
            if (cmd.hasOption('v') && !cmd.getOptionValue('v').equalsIgnoreCase("auto")) {
                apiVersion = WeaveClientFactory.stringToApiVersion(cmd.getOptionValue('v'));
            } else {
                //TODO - Auto-discover API version if not explicitly set
                System.err.println("Auto discover not implemented");
                System.exit(1);
            }

            if (apiVersion == ApiVersion.v1_1) {

                //Get host and credential details
                accountServer = cmd.getOptionValue('s');
                username = cmd.getOptionValue('u');
                password = cmd.getOptionValue('p');
                synckey = cmd.getOptionValue('k');

                if ((accountServer == null || accountServer.isEmpty()) || (username == null || username.isEmpty())
                        || (password == null || password.isEmpty()) || (synckey == null || synckey.isEmpty())) {
                    System.err.println(
                            "server, username, password and synckey are required parameters for account registration");
                    System.exit(1);
                }

                //Validate URI syntax
                try {
                    URI.create(accountServer);
                } catch (IllegalArgumentException e) {
                    System.err.printf("'%s' is not a valid URI, i.e. should be http(s)://example.com\n",
                            accountServer);
                    System.exit(1);
                }

                LegacyV5AccountParams fslParams = new LegacyV5AccountParams();
                fslParams.accountServer = accountServer;
                fslParams.user = username;
                fslParams.password = password;
                fslParams.syncKey = synckey;

                try {
                    account = new LegacyV5Account();
                    account.init(fslParams);
                } catch (WeaveException e) {
                    System.err.println(String.format("Couldn't initialise account - %s", e.getMessage()));
                    System.exit(1);
                }

            } else if (apiVersion == ApiVersion.v1_5) {

                //Get host and credential details
                if (cmd.hasOption('s') || cmd.hasOption('t')) {
                    accountServer = cmd.getOptionValue('s');
                    tokenServer = cmd.getOptionValue('t');
                } else {
                    //Default to Mozilla FxA servers
                    accountServer = WeaveClientV1_5.DEFAULT_ACCOUNT_SERVER;
                    tokenServer = WeaveClientV1_5.DEFAULT_TOKEN_SERVER;
                }

                username = cmd.getOptionValue('u');
                password = cmd.getOptionValue('p');

                if ((accountServer == null || accountServer.isEmpty())
                        || (tokenServer == null || tokenServer.isEmpty())
                        || (username == null || username.isEmpty()) || (password == null || password.isEmpty())) {
                    System.err.println(
                            "account-server, token-server, username and password are required parameters for account registration");
                    System.exit(1);
                }

                //Validate URI syntax
                try {
                    URI.create(accountServer);
                } catch (IllegalArgumentException e) {
                    System.err.printf("'%s' is not a valid URI, i.e. should be http(s)://example.com\n",
                            accountServer);
                    System.exit(1);
                }

                FxAccountParams fxaParams = new FxAccountParams();
                fxaParams.accountServer = accountServer;
                fxaParams.tokenServer = tokenServer;
                fxaParams.user = username;
                fxaParams.password = password;

                try {
                    account = new FxAccount();
                    account.init(fxaParams);
                } catch (WeaveException e) {
                    System.err.println(String.format("Couldn't initialise account - %s", e.getMessage()));
                    System.exit(1);
                }

            } else {
                Log.getInstance().warn(String.format("API version %s not supported", apiVersion));
            }

        }

        //Initialise weave client from account params
        WeaveClient weaveClient = null;

        try {
            weaveClient = WeaveClientFactory.getInstance(account);
        } catch (WeaveException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }

        //Set collection
        collection = cmd.getOptionValue('c', null);
        if (collection == null || collection.isEmpty()) {
            System.err.println("collection is a required parameter");
            System.exit(1);
        }

        //Optionally get ID
        if (cmd.hasOption('i')) {
            id = cmd.getOptionValue('i');
        }

        if (cmd.hasOption('m')) {
            if (id == null) {
                System.err.println("id is required when using the modify option");
                System.exit(1);
            }
            payload = cmd.getOptionValue('m');
        }

        if (cmd.hasOption('d')) {
            if (id == null) {
                System.err.println("id is required when using the delete option");
                System.exit(1);
            } else if (payload != null) {
                System.err.println("the modify and delete options cannot be used together");
                System.exit(1);
            }
            delete = true;
        }

        if (cmd.hasOption('n')) {
            if (!(id == null && payload == null)) {
                //quietly do nothing
            } else {
                info = true;
            }
        }

        if (cmd.hasOption('o')) {
            if (!(id == null && payload == null)) {
                //quietly do nothing
            } else {
                ids = true;
            }
        }

        if (cmd.hasOption("plaintext")) {
            encrypt = false;
        }

        if (payload != null) {

            WeaveBasicObject wbo = new WeaveBasicObject(id, null, null, null, payload);

            Double modified = null;
            try {
                modified = weaveClient.put(collection, id, wbo, encrypt);
            } catch (WeaveException e) {
                System.err.println(e.getMessage());
                System.exit(1);
            }
            System.out.println(String.format("modified: %f", modified));

        } else if (delete) {

            try {
                weaveClient.delete(collection, id);
            } catch (NotFoundException e) {
                System.err.println(
                        String.format("Collection '%s' item '%s' not found - " + e.getMessage(), collection, id));
                System.exit(1);
            } catch (WeaveException e) {
                System.err.println(e.getMessage());
                System.exit(1);
            }

            //TODO - Handle collections

        } else if (info) {

            WeaveCollectionInfo colinfo = null;
            try {
                colinfo = weaveClient.getCollectionInfo(collection);
            } catch (WeaveException e) {
                System.err.println(e.getMessage());
                System.exit(1);
            } catch (NotFoundException e) {
                System.err.println(e.getMessage());
                System.exit(1);
            }

            System.out.println(colinfo.toString());

        } else if (ids) {
            try {
                String[] colIds = weaveClient.getCollectionIds(collection, null, null, null, null, null, null, null,
                        null);
                for (String colId : colIds) {
                    System.out.println(colId);
                }
            } catch (WeaveException e) {
                System.err.println(e.getMessage());
                System.exit(1);
            } catch (NotFoundException e) {
                System.err.println(e.getMessage());
                System.exit(1);
            }

        } else {

            try {
                if (id != null) {
                    WeaveBasicObject wbo = weaveClient.get(collection, id, encrypt);
                    System.out.print(wbo.getPayload());
                } else {
                    WeaveBasicObject[] colWbo = weaveClient.getCollection(collection, null, null, null, null, null,
                            null, null, null, null, encrypt);
                    for (int i = 0; i < colWbo.length; i++) {
                        System.out.println(colWbo[i].getPayload().trim());
                    }
                }
            } catch (NotFoundException e) {
                System.err.println(String.format("Weave object not found - %s", e.getMessage()));
                System.exit(1);
            } catch (WeaveException e) {
                System.err.println(e.getMessage());
                System.exit(1);
            }

            //System.out.println("Threads:");
            //List<Thread> threads = getThreads();
            //for (Thread thread: threads) {
            //   System.out.println(String.format("thread: %s (%s) isAlive: %s", thread.getName(), thread.getClass().getCanonicalName(), thread.isAlive()));
            //}
        }

    }
}