org.duracloud.stitch.FileStitcherDriver Maven / Gradle / Ivy
/*
* The contents of this file are subject to the license and copyright
* detailed in the LICENSE and NOTICE files at the root of the source
* tree and available online at
*
* http://duracloud.org/license/
*/
package org.duracloud.stitch;
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.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.duracloud.chunk.FileChunker;
import org.duracloud.client.ContentStore;
import org.duracloud.client.ContentStoreManager;
import org.duracloud.client.ContentStoreManagerImpl;
import org.duracloud.common.error.DuraCloudRuntimeException;
import org.duracloud.common.model.Credential;
import org.duracloud.domain.Content;
import org.duracloud.error.ContentStoreException;
import org.duracloud.stitch.datasource.DataSource;
import org.duracloud.stitch.datasource.impl.DuraStoreDataSource;
import org.duracloud.stitch.impl.FileStitcherImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* This class is the command-line driver for reconstituting a single content
* item which has previously been chunked into DuraStore.
*
* @author Andrew Woods
* Date: 9/5/11
*/
public class FileStitcherDriver {
private Logger log = LoggerFactory.getLogger(FileStitcherDriver.class);
private FileStitcher stitcher;
public FileStitcherDriver(DataSource dataSource) {
this.stitcher = new FileStitcherImpl(dataSource);
}
/**
* This method retrieves the chunks manifest specified by the arg space-id
* and manifest-id (content-id), then reconstitues the chunks defined in
* the manifest into the original file at the arg to-directory.
*
* @param spaceId containing chunks manifest
* @param manifestId of the manifest (content-id)
* @param toDir destination of reconstituted original content item
* @throws Exception on error
*/
public void stitch(String spaceId, String manifestId, File toDir)
throws Exception {
verifyDir(toDir);
Content content = stitcher.getContentFromManifest(spaceId, manifestId);
writeContentToDir(content, toDir);
}
private void verifyDir(File dir) throws Exception {
if (!dir.isDirectory() && !dir.mkdirs()) {
throw new DuraCloudRuntimeException("Invalid dir: " + dir);
}
try {
File tmp = new File(dir, "remove-me.txt");
FileOutputStream fos = new FileOutputStream(tmp);
fos.write("hello".getBytes());
IOUtils.closeQuietly(fos);
FileUtils.deleteQuietly(tmp);
} catch (IOException e) {
StringBuilder sb = new StringBuilder();
sb.append("User must have permissions to write to the directory: ");
sb.append(dir.getAbsolutePath());
throw new Exception(sb.toString(), e);
}
}
private void writeContentToDir(Content content, File toDir) {
File outFile = new File(toDir, content.getId());
log.info("Writing to '{}'.", outFile.getAbsolutePath());
OutputStream outputStream = null;
try {
// Create any needed subdirectories
File parentDir = outFile.getParentFile();
if(!parentDir.exists()) {
parentDir.mkdirs();
parentDir.setWritable(true);
}
// Write content
outputStream = new FileOutputStream(outFile);
IOUtils.copyLarge(content.getStream(), outputStream);
} catch (IOException e) {
StringBuilder msg = new StringBuilder();
msg.append("Error writing content: ");
msg.append(content.getId());
msg.append(" to output file: ");
msg.append(outFile.getAbsolutePath());
throw new DuraCloudRuntimeException(msg.toString(), e);
} finally {
IOUtils.closeQuietly(outputStream);
}
}
private static Options getOptions() {
Option host = new Option("h",
"host",
true,
"hostname of duracloud instance");
Option port = new Option("r",
"port",
true,
"port of duracloud instance");
Option username = new Option("u",
"username",
true,
"username of duracloud instance");
Option password = new Option("p",
"password",
true,
"password of duracloud instance");
Option storeId = new Option("i",
"store-id",
true,
"store-id of duracloud storage provider");
Option spaceId = new Option("s",
"space-id",
true,
"space-id of duracloud space where " +
"manifest and chunks reside");
Option manifestId = new Option("m",
"manifest-id",
true,
"manifest-id of chunks manifest");
Option toDir = new Option("d",
"to-dir",
true,
"destination directory of full content");
host.setRequired(true);
port.setRequired(false);
username.setRequired(true);
password.setRequired(true);
storeId.setRequired(false);
spaceId.setRequired(true);
manifestId.setRequired(true);
toDir.setRequired(true);
Options options = new Options();
options.addOption(host);
options.addOption(port);
options.addOption(username);
options.addOption(password);
options.addOption(storeId);
options.addOption(spaceId);
options.addOption(manifestId);
options.addOption(toDir);
return options;
}
private static CommandLine parseArgs(String[] args) {
CommandLineParser parser = new GnuParser();
CommandLine cmd = null;
try {
cmd = parser.parse(getOptions(), args);
} catch (ParseException e) {
System.err.println(e);
die();
}
return cmd;
}
private static void usage() {
HelpFormatter help = new HelpFormatter();
help.setWidth(80);
help.printHelp(FileChunker.class.getCanonicalName(), getOptions());
}
private static void die() {
usage();
System.exit(1);
}
/**
* Main
*/
public static void main(String[] args) {
CommandLine cmd = parseArgs(args);
String spaceId = cmd.getOptionValue("space-id");
String manifestId = cmd.getOptionValue("manifest-id");
String toDir = cmd.getOptionValue("to-dir");
// do the stitching.
try {
DataSource dataSource = getDataSource(cmd);
FileStitcherDriver driver = new FileStitcherDriver(dataSource);
driver.stitch(spaceId, manifestId, new File(toDir));
} catch (Exception e) {
System.err.println("Error stitching content: " + e.getMessage());
e.printStackTrace(System.err);
System.exit(1);
}
System.out.println(
"Successfully downloaded: " + spaceId + "/" + manifestId);
}
private static DataSource getDataSource(CommandLine cmd)
throws ContentStoreException {
String host = cmd.getOptionValue("host");
String port = "443";
if (cmd.hasOption("port")) {
port = cmd.getOptionValue("port");
}
String username = cmd.getOptionValue("username");
String password = cmd.getOptionValue("password");
ContentStoreManager mgr = new ContentStoreManagerImpl(host, port);
mgr.login(getCredentials(username, password));
ContentStore contentStore;
if (cmd.hasOption("store-id")) {
contentStore = mgr.getContentStore(cmd.getOptionValue("store-id"));
} else {
contentStore = mgr.getPrimaryContentStore();
}
return new DuraStoreDataSource(contentStore);
}
private static Credential getCredentials(String username, String password) {
if (null == username || null == password) {
String border = "**************\n";
StringBuilder msg = new StringBuilder(border);
msg.append("If either username or password are provided,\n");
msg.append("they both must be provided.\n");
msg.append(border);
System.out.println(msg);
die();
}
return new Credential(username, password);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy