All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.nosqlbench.engine.cli.NBCLIScenarioParser Maven / Gradle / Ivy

package io.nosqlbench.engine.cli;

import io.nosqlbench.engine.api.activityconfig.StatementsLoader;
import io.nosqlbench.engine.api.activityconfig.yaml.Scenarios;
import io.nosqlbench.engine.api.activityconfig.yaml.StmtsDocList;
import io.nosqlbench.engine.api.exceptions.BasicError;
import io.nosqlbench.engine.api.util.NosqlBenchFiles;
import io.nosqlbench.engine.api.util.StrInterpolator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.file.Path;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NBCLIScenarioParser {

    public final static String SILENT_LOCKED = "==";
    public final static String VERBOSE_LOCKED = "===";
    public final static String UNLOCKED = "=";

    private final static Logger logger = LoggerFactory.getLogger(NBCLIScenarioParser.class);

    public static boolean isFoundWorkload(String word) {
        Optional workloadPath = NosqlBenchFiles.findOptionalPath(word, "yaml", "activities");
        return workloadPath.isPresent();
    }

    public static void parseScenarioCommand(LinkedList arglist) {

        String workloadName = arglist.removeFirst();
        Optional workloadPathSearch = NosqlBenchFiles.findOptionalPath(workloadName, "yaml", "activities");
        Path workloadPath = workloadPathSearch.orElseThrow();

        List scenarioNames = new ArrayList<>();
        while (arglist.size() > 0
            && !arglist.peekFirst().contains("=")
            && !arglist.peekFirst().startsWith("-")
            && !NBCLIOptions.RESERVED_WORDS.contains(arglist.peekFirst())) {
            scenarioNames.add(arglist.removeFirst());
        }
        if (scenarioNames.size() == 0) {
            scenarioNames.add("default");
        }

        // Load in user's CLI options
        LinkedHashMap userParams = new LinkedHashMap<>();
        while (arglist.size() > 0
            && arglist.peekFirst().contains("=")
            && !arglist.peekFirst().startsWith("-")) {
            String[] arg = arglist.removeFirst().split("=");
            arg[0] = Synonyms.canonicalize(arg[0], logger);
            if (userParams.containsKey(arg[0])) {
                throw new BasicError("duplicate occurrence of option on command line: " + arg[0]);
            }
            userParams.put(arg[0], arg[1]);
        }
        StrInterpolator userParamsInterp = new StrInterpolator(userParams);

        // This will hold the command to be prepended to the main arglist
        LinkedList buildCmdBuffer = new LinkedList<>();

        for (String scenarioName : scenarioNames) {

            // Load in named scenario
            StmtsDocList stmts = StatementsLoader.load(logger, workloadPath.toString());
            Scenarios scenarios = stmts.getDocScenarios();
            List cmds = scenarios.getNamedScenario(scenarioName);
            if (cmds == null) {
                throw new BasicError("Unable to find named scenario '" + scenarioName + "' in workload '" + workloadName
                    + "', but you can pick from " + String.join(",", scenarios.getScenarioNames()));
            }

            Pattern cmdpattern = Pattern.compile("(?\\w+)((?=+)(?.+))?");
            for (String cmd : cmds) {  // each command line of the named scenario
                cmd = userParamsInterp.apply(cmd);
                LinkedHashMap usersCopy = new LinkedHashMap<>(userParams);
                LinkedHashMap cmdline = new LinkedHashMap<>();

                String[] cmdparts = cmd.split(" ");
                for (String cmdpart : cmdparts) {
                    Matcher matcher = cmdpattern.matcher(cmdpart);
                    if (!matcher.matches()) {
                        throw new BasicError("Unable to recognize scenario cmd spec in '" + cmdpart + "'");
                    }
                    String name = Synonyms.canonicalize(matcher.group("name"), logger);
                    String oper = matcher.group("oper");
                    String val = matcher.group("val");
                    cmdline.put(name, new CmdArg(name, oper, val));
                }

                LinkedHashMap builtcmd = new LinkedHashMap<>();

                for (CmdArg cmdarg : cmdline.values()) {
                    if (usersCopy.containsKey(cmdarg.getName())) {
                        cmdarg = cmdarg.override(usersCopy.remove(cmdarg.getName()));
                    }
                    builtcmd.put(cmdarg.getName(), cmdarg.toString());
                }
                usersCopy.forEach((k, v) -> builtcmd.put(k, k + "=" + v));
                if (!builtcmd.containsKey("workload")) {
                    builtcmd.put("workload", "workload=" + workloadPath.toString());
                }

                logger.debug("Named scenario built command: " + String.join(" ", builtcmd.values()));
                buildCmdBuffer.addAll(builtcmd.values());
            }

        }
        buildCmdBuffer.descendingIterator().forEachRemaining(arglist::addFirst);

    }

    private final static class CmdArg {
        private final String name;
        private final String operator;
        private final String value;
        private String scenarioName;

        public CmdArg(String name, String operator, String value) {
            this.name = name;
            this.operator = operator;
            this.value = value;
        }

        public boolean isReassignable() {
            return "=".equals(operator);
        }
        public boolean isFinalSilent() {
            return "==".equals(operator);
        }
        public boolean isFinalVerbose() {
            return "===".equals(operator);
        }


        public CmdArg override(String value) {
            if (isReassignable()) {
                return new CmdArg(this.name, this.operator, value);
            } else if (isFinalSilent()) {
                return this;
            } else if (isFinalVerbose()) {
                throw new BasicError("Unable to reassign value for locked param '" + name + operator + value + "'");
            } else {
                throw new RuntimeException("impossible!");
            }
        }

        @Override
        public String toString() {
            return name + (operator != null ? "=" : "") + (value != null ? value : "");
        }

        public String getName() {
            return name;
        }
    }

//    private static void parseWorkloadYamlCmds(String yamlPath, LinkedList arglist, String scenarioName) {
//        StmtsDocList stmts = StatementsLoader.load(logger, yamlPath);
//
//        Scenarios scenarios = stmts.getDocScenarios();
//
//        String scenarioName = "default";
//        if (scenarioName != null) {
//            scenarioName = scenarioName;
//        }
//
//        List cmds = scenarios.getNamedScenario(scenarioName);
//
//
//        Map paramMap = new HashMap<>();
//        while (arglist.size() > 0 && arglist.peekFirst().contains("=")) {
//            String arg = arglist.removeFirst();
//            String oldArg = arg;
//            arg = Synonyms.canonicalize(arg, logger);
//
//            for (int i = 0; i < cmds.size(); i++) {
//                String yamlCmd = cmds.get(i);
//                String[] argArray = arg.split("=");
//                String argKey = argArray[0];
//                String argValue = argArray[1];
//                if (!yamlCmd.contains(argKey)) {
//                    cmds.set(i, yamlCmd + " " + arg);
//                } else {
//                    paramMap.put(argKey, argValue);
//                }
//            }
//        }
//
//
//        if (cmds == null) {
//            List names = scenarios.getScenarioNames();
//            throw new RuntimeException("Unknown scenario name, make sure the scenario name you provide exists in the workload definition (yaml):\n" + String.join(",", names));
//        }
//
//        for (String cmd : cmds) {
//            String[] cmdArray = cmd.split(" ");
//
//            for (String parameter : cmdArray) {
//                if (parameter.contains("=")) {
//                    if (!parameter.contains("TEMPLATE(") && !parameter.contains("<<")) {
//                        String[] paramArray = parameter.split("=");
//                        paramMap.put(paramArray[0], paramArray[1]);
//                    }
//                }
//            }
//
//            StrSubstitutor sub1 = new StrSubstitutor(paramMap, "<<", ">>", '\\', ",");
//            StrSubstitutor sub2 = new StrSubstitutor(paramMap, "TEMPLATE(", ")", '\\', ",");
//
//            cmd = sub2.replace(sub1.replace(cmd));
//
//            if (cmd.contains("yaml=") || cmd.contains("workload=")) {
//                parse(cmd.split(" "));
//            } else {
//                parse((cmd + " workload=" + yamlPath).split(" "));
//            }
//
//            // Is there a better way to do this than regex?
//
//        }
//    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy