/**
* Copyright 2016 LinkedIn Corp. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*/
package com.github.ambry.utils;
import java.io.IOException;
import java.util.ArrayList;
import joptsimple.ArgumentAcceptingOptionSpec;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import joptsimple.OptionSpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Abstraction class for all the parameters we expect to receive to start Ambry frontend and data nodes.
*/
public class InvocationOptions {
public final String hardwareLayoutFilePath;
public final String partitionLayoutFilePath;
public final String serverPropsFilePath;
private final Logger logger = LoggerFactory.getLogger(getClass());
/**
* Parses the arguments provided and extracts them into variables that can be retrieved through APIs.
* @param args the command line argument list.
* @throws InstantiationException if all required arguments were not provided.
* @throws IOException if help text could not be printed.
*/
public InvocationOptions(String args[]) throws InstantiationException, IOException {
OptionParser parser = new OptionParser();
ArgumentAcceptingOptionSpec<String> hardwareLayoutFilePath =
parser.accepts("hardwareLayoutFilePath", "Path to hardware layout file")
.withRequiredArg()
.describedAs("hardwareLayoutFilePath")
.ofType(String.class);
ArgumentAcceptingOptionSpec<String> partitionLayoutFilePath =
parser.accepts("partitionLayoutFilePath", "Path to partition layout file")
.withRequiredArg()
.describedAs("partitionLayoutFilePath")
.ofType(String.class);
ArgumentAcceptingOptionSpec<String> serverPropsFilePath =
parser.accepts("serverPropsFilePath", "Path to server properties file")
.withRequiredArg()
.describedAs("serverPropsFilePath")
.ofType(String.class);
ArrayList<OptionSpec<?>> requiredArgs = new ArrayList<>();
requiredArgs.add(hardwareLayoutFilePath);
requiredArgs.add(partitionLayoutFilePath);
requiredArgs.add(serverPropsFilePath);
OptionSet options = parser.parse(args);
if (hasRequiredOptions(requiredArgs, options)) {
this.hardwareLayoutFilePath = options.valueOf(hardwareLayoutFilePath);
logger.trace("Hardware layout file path: {}", this.hardwareLayoutFilePath);
this.partitionLayoutFilePath = options.valueOf(partitionLayoutFilePath);
logger.trace("Partition layout file path: {}", this.partitionLayoutFilePath);
this.serverPropsFilePath = options.valueOf(serverPropsFilePath);
logger.trace("Server properties file path: {}", this.serverPropsFilePath);
} else {
parser.printHelpOn(System.err);
throw new InstantiationException("Did not receive all required arguments for starting RestServer");
}
}
/**
* Checks if all required arguments are present. Prints the ones that are not.
* @param requiredArgs the list of required arguments.
* @param options the list of received options.
* @return whether required options are present.
*/
private boolean hasRequiredOptions(ArrayList<OptionSpec<?>> requiredArgs, OptionSet options) {
boolean haveAll = true;
for (OptionSpec opt : requiredArgs) {
if (!options.has(opt)) {
System.err.println("Missing required argument " + opt);
haveAll = false;
}
}
return haveAll;
}
}