S3TaskArgs.java
/*
* This file is part of Waarp Project (named also Waarp or GG).
*
* Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
* tags. See the COPYRIGHT.txt in the distribution for a full listing of
* individual contributors.
*
* All Waarp Project is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* Waarp 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* Waarp . If not, see <http://www.gnu.org/licenses/>.
*/
package org.waarp.openr66.context.task;
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.waarp.common.logging.WaarpLogger;
import org.waarp.common.logging.WaarpLoggerFactory;
import org.waarp.common.utility.ParametersChecker;
import org.waarp.openr66.s3.taskfactory.S3TaskFactory;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* S3 GET Task<br>
* <p>
* Result of arguments will be as a S3 GET command.<br>
* Format is the following:<br>
* "-URL url of S3 service <br>
* -accessKey access Key for S3 service <br>
* -secretKey secret Key for S3 service <br>
* -bucketName bucket Name where to retrieve the object <br>
* -sourceName source Name from the bucket to select the final Object <br>
* -file final File path (absolute or relative from IN path) <br>
* [-getTags [* or list of tag names comma separated without space]]" <br>
* -targetName source Name from the bucket to select the final Object <br>
* [-setTags 'name:value,...' without space]" <br>
*/
public class S3TaskArgs {
private static final WaarpLogger logger =
WaarpLoggerFactory.getLogger(S3TaskArgs.class);
public static final String ARG_URL = "URL";
public static final String ARG_ACCESS_KEY = "accessKey";
public static final String ARG_SECRET_KEY = "secretKey";
public static final String ARG_BUCKET_NAME = "bucketName";
public static final String ARG_SOURCE_NAME = "sourceName";
public static final String ARG_TARGET_NAME = "targetName";
public static final String ARG_FILE = "file";
public static final String ARG_GET_TAGS = "getTags";
public static final String ARG_SET_TAGS = "setTags";
private static final Option OPTION_URL =
Option.builder(ARG_URL).required(true).hasArg(true)
.desc("Specify the URL to operate on").build();
private static final Option OPTION_ACCESS_KEY =
Option.builder(ARG_ACCESS_KEY).required(true).hasArg(true)
.desc("Specify the Access Key to operate with").build();
private static final Option OPTION_SECRET_KEY =
Option.builder(ARG_SECRET_KEY).required(true).hasArg(true)
.desc("Specify the Secret Key to operate with").build();
private static final Option OPTION_BUCKET_NAME =
Option.builder(ARG_BUCKET_NAME).required(true).hasArg(true)
.desc("Specify the Bucket Name to operate with").build();
private static final Option OPTION_SOURCE_NAME =
Option.builder(ARG_SOURCE_NAME).required(true).hasArg(true)
.desc("Specify the Source Name to operate on").build();
private static final Option OPTION_TARGET_NAME =
Option.builder(ARG_TARGET_NAME).required(true).hasArg(true)
.desc("Specify the Target Name to operate on").build();
private static final Option OPTION_FILE =
Option.builder(ARG_FILE).required(true).hasArg(true)
.desc("Specify the File to operate on").build();
private static final Option OPTION_GET_TAGS =
Option.builder(ARG_GET_TAGS).required(false).hasArg(true).desc(
"Specify the Tags to retrieve: * or comma separated list without space")
.build();
private static final Option OPTION_SET_TAGS =
Option.builder(ARG_SET_TAGS).required(false).hasArg(true).desc(
"Specify the Tags to set: key1:value1,key2:value2 comma separated list without space")
.build();
private static final Options S3_GET_OPTIONS =
new Options().addOption(OPTION_URL).addOption(OPTION_ACCESS_KEY)
.addOption(OPTION_SECRET_KEY).addOption(OPTION_BUCKET_NAME)
.addOption(OPTION_SOURCE_NAME).addOption(OPTION_FILE)
.addOption(OPTION_GET_TAGS);
private static final Options S3_PUT_OPTIONS =
new Options().addOption(OPTION_URL).addOption(OPTION_ACCESS_KEY)
.addOption(OPTION_SECRET_KEY).addOption(OPTION_BUCKET_NAME)
.addOption(OPTION_TARGET_NAME).addOption(OPTION_SET_TAGS);
private static final Options S3_DELETE_OPTIONS =
new Options().addOption(OPTION_URL).addOption(OPTION_ACCESS_KEY)
.addOption(OPTION_SECRET_KEY).addOption(OPTION_BUCKET_NAME)
.addOption(OPTION_SOURCE_NAME);
protected static final String EMPTY_STRING_NOT_ALLOWED =
"Empty String not allowed";
/**
* Print to standard output the help of this command
*/
public static void printHelp(final S3TaskFactory.S3TaskType type,
final Options options) {
final HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(type.name(), options);
}
public static S3TaskArgs getS3Params(final S3TaskFactory.S3TaskType type,
final int rank, final String[] args) {
if (args == null || args.length == 0) {
logger.error("Arguments cannot be empty or null");
return null;
}
final String[] realArgs = getRealArgs(rank, args);
final CommandLineParser parser = new DefaultParser();
final Options options;
switch (type) {
case S3GET:
case S3GETDELETE:
options = S3_GET_OPTIONS;
break;
case S3PUT:
case S3PUTR66DELETE:
options = S3_PUT_OPTIONS;
break;
case S3DELETE:
options = S3_DELETE_OPTIONS;
break;
default:
logger.error("Unknown Task {}", type);
return null;
}
try {
final CommandLine cmd = parser.parse(options, realArgs, true);
final String surl = cmd.getOptionValue(ARG_URL);
final URL url = new URL(surl);
final String accessKey = cmd.getOptionValue(ARG_ACCESS_KEY);
final String secretKey = cmd.getOptionValue(ARG_SECRET_KEY);
final String bucketName =
cmd.getOptionValue(ARG_BUCKET_NAME).toLowerCase();
final String sourceName =
cmd.hasOption(ARG_SOURCE_NAME)? cmd.getOptionValue(ARG_SOURCE_NAME) :
null;
final String targetName =
cmd.hasOption(ARG_TARGET_NAME)? cmd.getOptionValue(ARG_TARGET_NAME) :
null;
final String sfile =
cmd.hasOption(ARG_FILE)? cmd.getOptionValue(ARG_FILE) : null;
final File file;
if (sfile != null) {
file = new File(sfile);
} else {
file = null;
}
final String sgetTags =
cmd.hasOption(ARG_GET_TAGS)? cmd.getOptionValue(ARG_GET_TAGS) : null;
Set<String> getTags = null;
if (ParametersChecker.isNotEmpty(sgetTags)) {
getTags = new HashSet<>();
final String[] keys = sgetTags.split(","); // NOSONAR
boolean star = false;
for (final String key : keys) {
if (key.equalsIgnoreCase("*")) {
star = true;
break;
}
if (key.isEmpty()) {
printHelp(type, options);
logger.error("Arguments GetTags are incorrect: {}", sgetTags);
return null;
}
getTags.add(key);
}
if (star) {
getTags.clear();
}
}
final String ssetTags =
cmd.hasOption(ARG_SET_TAGS)? cmd.getOptionValue(ARG_SET_TAGS) : null;
Map<String, String> setTags = null;
if (ParametersChecker.isNotEmpty(ssetTags)) {
setTags = new HashMap<>();
final String[] keyvalues = ssetTags.split(","); // NOSONAR
for (final String key : keyvalues) {
if (key.isEmpty()) {
printHelp(type, options);
logger.error("Arguments SetTags are incorrect: {}", ssetTags);
return null;
}
final String[] dual = key.split(":");
if (dual.length != 2 || dual[0].isEmpty() || dual[1].isEmpty()) {
printHelp(type, options);
logger.error("Arguments SetTags are incorrect: {}", ssetTags);
return null;
}
setTags.put(dual[0], dual[1]);
}
}
return new S3TaskArgs(type, url, accessKey, secretKey, bucketName,
sourceName, targetName, file, getTags, setTags);
} catch (final ParseException | MalformedURLException e) {
printHelp(type, options);
logger.error("Arguments are incorrect: {}", e.getMessage());
return null;
}
}
/**
* Finalize the real arguments to parse
*
* @param rank
* @param args
*
* @return the real arguments
*/
private static String[] getRealArgs(final int rank, final String[] args) {
return rank == 0? args : Arrays.copyOfRange(args, rank, args.length);
}
private final URL url;
private final String accessKey;
private final String secretKey;
private final String bucketName;
private final String sourceName;
private final String targetName;
private final File file;
private final Set<String> getTags;
private final boolean getTag;
private final Map<String, String> setTags;
public S3TaskArgs(final S3TaskFactory.S3TaskType type, final URL url,
final String accessKey, final String secretKey,
final String bucketName, final String sourceName,
final String targetName, final File file,
final Set<String> getTags,
final Map<String, String> setTags) {
ParametersChecker.checkParameter(EMPTY_STRING_NOT_ALLOWED, accessKey,
secretKey, bucketName);
if ((type == S3TaskFactory.S3TaskType.S3GET ||
type == S3TaskFactory.S3TaskType.S3GETDELETE ||
type == S3TaskFactory.S3TaskType.S3DELETE) &&
ParametersChecker.isEmpty(sourceName) && file == null) {
throw new IllegalArgumentException(EMPTY_STRING_NOT_ALLOWED);
}
if ((type == S3TaskFactory.S3TaskType.S3PUT ||
type == S3TaskFactory.S3TaskType.S3PUTR66DELETE) &&
ParametersChecker.isEmpty(targetName)) {
throw new IllegalArgumentException(EMPTY_STRING_NOT_ALLOWED);
}
this.url = url;
this.accessKey = accessKey;
this.secretKey = secretKey;
this.bucketName = bucketName;
this.sourceName = sourceName;
this.targetName = targetName;
this.file = file;
this.getTags = getTags;
this.setTags = setTags;
this.getTag = getTags != null;
}
public final URL getUrl() {
return url;
}
public final String getAccessKey() {
return accessKey;
}
public final String getSecretKey() {
return secretKey;
}
public final String getBucketName() {
return bucketName;
}
public final String getSourceName() {
return sourceName;
}
public final String getTargetName() {
return targetName;
}
public final File getFile() {
return file;
}
public final Set<String> getGetTags() {
return getTags;
}
public final boolean getGetTag() {
return getTag;
}
public final Map<String, String> getSetTags() {
return setTags;
}
}