org.diqube.tool.im.IdentityToolFunction.java Source code

Java tutorial

Introduction

Here is the source code for org.diqube.tool.im.IdentityToolFunction.java

Source

/**
 * diqube: Distributed Query Base.
 *
 * Copyright (C) 2015 Bastian Gloeckle
 *
 * This file is part of diqube.
 *
 * diqube is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.diqube.tool.im;

import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.diqube.remote.query.thrift.IdentityService;
import org.diqube.tool.ToolFunction;
import org.diqube.tool.ToolFunctionName;
import org.diqube.tool.info.Info;
import org.diqube.util.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;

/**
 * Tool function that interacts with {@link IdentityService}.
 *
 * @author Bastian Gloeckle
 */
@ToolFunctionName(IdentityToolFunction.FUNCTION_NAME)
public class IdentityToolFunction implements ToolFunction {
    public static final Logger logger = LoggerFactory.getLogger(IdentityToolFunction.class);

    private static final String BASE_PKG = "org.diqube.tool.im";

    public static final String FUNCTION_NAME = "im";

    public static final String OPT_HELP = "h";
    public static final String OPT_ACTUAL_FUNCTION = "f";
    public static final String OPT_LOGIN_USER = "lu";
    public static final String OPT_LOGIN_PASSWORD = "lp";
    public static final String OPT_PARAM_USER = "u";
    public static final String OPT_PARAM_PASSWORD = "p";
    public static final String OPT_PARAM_PERMISSION = "a";
    public static final String OPT_PARAM_PERMISSION_OBJECT = "o";
    public static final String OPT_PARAM_EMAIL = "e";
    public static final String OPT_SERVER = "s";

    private Map<String, Pair<AbstractActualIdentityToolFunction, IsActualIdentityToolFunction>> actualFunctions;

    @Override
    public void execute(String[] args) {
        actualFunctions = loadActualFunctions();

        Options cliOpt = createCliOptions();
        CommandLineParser parser = new DefaultParser();
        CommandLine cmd = null;
        boolean showHelp = false;
        String actualFunctionNameForHelp = null;
        try {
            cmd = parser.parse(cliOpt, args);

            if (cmd.hasOption(OPT_HELP)) {
                showHelp = true;
                actualFunctionNameForHelp = cmd.getOptionValue(OPT_HELP);
            }
        } catch (ParseException e) {
            logger.error(e.getMessage());
            showHelp = true;

            // check if there is a detailed -h option
            try {
                Options helpCliOptions = createCliOptionsOnlyHelp();
                cmd = new DefaultParser().parse(helpCliOptions, args);

                if (cmd.hasOption(OPT_HELP)) {
                    showHelp = true;
                    actualFunctionNameForHelp = cmd.getOptionValue(OPT_HELP);
                }
            } catch (ParseException e2) {
                // swallow, we show help anyway.
            }
        }

        if (showHelp) {
            if (actualFunctionNameForHelp != null) {
                if (actualFunctions.containsKey(actualFunctionNameForHelp)) {
                    System.out.println("Help for function '" + actualFunctionNameForHelp + "':");
                    System.out.println();
                    System.out
                            .println(actualFunctions.get(actualFunctionNameForHelp).getRight().shortDescription());
                    return;
                }
                System.out.println("Unknown function: " + actualFunctionNameForHelp);
            }
            HelpFormatter formatter = new HelpFormatter();
            formatter.printHelp(Info.FUNCTION_NAME + " [options]",
                    "\nInteracts with the identity service of a diqube server.\n\n", cliOpt, "");
            return;
        }

        String function = cmd.getOptionValue(OPT_ACTUAL_FUNCTION);
        String loginUser = cmd.getOptionValue(OPT_LOGIN_USER);
        String loginPassword = cmd.getOptionValue(OPT_LOGIN_PASSWORD);
        String paramUser = cmd.getOptionValue(OPT_PARAM_USER);
        String paramPassword = cmd.getOptionValue(OPT_PARAM_PASSWORD);
        String paramPermission = cmd.getOptionValue(OPT_PARAM_PERMISSION);
        String paramPermissionObject = cmd.getOptionValue(OPT_PARAM_PERMISSION_OBJECT);
        String paramEmail = cmd.getOptionValue(OPT_PARAM_EMAIL);
        String server = cmd.getOptionValue(OPT_SERVER);

        if (!actualFunctions.containsKey(function)) {
            logger.error("Unknown function '{}'", function);
            return;
        }

        AbstractActualIdentityToolFunction fn = actualFunctions.get(function).getLeft();

        fn.initializeGeneral(server, loginUser, loginPassword);
        fn.initializeOptionalParams(paramUser, paramPassword, paramPermission, paramPermissionObject, paramEmail);

        logger.info("Executing function '{}'...", function);

        fn.execute();

        logger.info("Function executed successfully.", function);
    }

    private Map<String, Pair<AbstractActualIdentityToolFunction, IsActualIdentityToolFunction>> loadActualFunctions() {
        try {
            Collection<ClassInfo> classInfos = ClassPath.from(getClass().getClassLoader())
                    .getTopLevelClassesRecursive(BASE_PKG);

            Map<String, Pair<AbstractActualIdentityToolFunction, IsActualIdentityToolFunction>> toolFunctions = new HashMap<>();

            for (ClassInfo classInfo : classInfos) {
                Class<?> clazz = classInfo.load();
                IsActualIdentityToolFunction isActualIdentityToolFunctionAnnotation = clazz
                        .getAnnotation(IsActualIdentityToolFunction.class);
                if (isActualIdentityToolFunctionAnnotation != null) {
                    AbstractActualIdentityToolFunction functionInstance = (AbstractActualIdentityToolFunction) clazz
                            .newInstance();

                    toolFunctions.put(isActualIdentityToolFunctionAnnotation.identityFunctionName(),
                            new Pair<>(functionInstance, isActualIdentityToolFunctionAnnotation));
                }
            }

            return toolFunctions;
        } catch (IOException | InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    private Options createCliOptions() {
        Options res = new Options();
        res.addOption(Option.builder(OPT_ACTUAL_FUNCTION).longOpt("function").numberOfArgs(1).argName("name")
                .desc("Name of the function to execute on the identity service (required). One of the following: "
                        + actualFunctions.keySet())
                .required().build());
        res.addOption(Option.builder(OPT_SERVER).longOpt("server").numberOfArgs(1).argName("ip:port")
                .desc("Server address of a running diqube server.").required().build());
        res.addOption(Option.builder(OPT_LOGIN_USER).longOpt("login-user").numberOfArgs(1).argName("name")
                .desc("Username to use for authentication at the identity service (required).").required().build());
        res.addOption(Option.builder(OPT_LOGIN_PASSWORD).longOpt("login-password").numberOfArgs(1)
                .argName("password").desc("Password to use for authentication at the identity service (required).")
                .required().build());

        res.addOption(Option.builder(OPT_PARAM_USER).longOpt("user").numberOfArgs(1).argName("name")
                .desc("Username to use as parameter to the function.").build());
        res.addOption(Option.builder(OPT_PARAM_PASSWORD).longOpt("password").numberOfArgs(1).argName("password")
                .desc("Password to use as parameter to the function.").build());
        res.addOption(Option.builder(OPT_PARAM_PERMISSION).longOpt("permission").numberOfArgs(1).argName("name")
                .desc("Permission to use as parameter to the function.").build());
        res.addOption(Option.builder(OPT_PARAM_PERMISSION_OBJECT).longOpt("object").numberOfArgs(1).argName("name")
                .desc("Permission object to use as parameter to the function.").build());
        res.addOption(Option.builder(OPT_PARAM_EMAIL).longOpt("email").numberOfArgs(1).argName("address")
                .desc("E-mail address to use as parameter to the function.").build());

        addHelpOption(res);

        return res;
    }

    private void addHelpOption(Options res) {
        res.addOption(Option.builder(OPT_HELP).longOpt("help").numberOfArgs(1).argName("function name")
                .desc("Show this help or the help of a specific function (see flag '" + OPT_ACTUAL_FUNCTION + "').")
                .build());
    }

    private Options createCliOptionsOnlyHelp() {
        Options res = new Options();
        addHelpOption(res);
        return res;
    }
}