1 package org.kuali.common.devops.archive.sweep; 2 3 import static java.lang.String.format; 4 import static java.util.Arrays.asList; 5 import static org.kuali.common.util.Encodings.UTF8; 6 import static org.kuali.common.util.base.Precondition.checkNotBlank; 7 import static org.kuali.common.util.log.Loggers.newLogger; 8 9 import java.io.File; 10 import java.io.IOException; 11 import java.util.List; 12 13 import org.kuali.common.core.build.ValidatingBuilder; 14 import org.kuali.common.core.cli.api.CommandLineService; 15 import org.kuali.common.core.cli.api.ExecRequest; 16 import org.kuali.common.core.cli.api.StringStreamConsumer; 17 import org.kuali.common.core.cli.plexus.PlexusCLIService; 18 import org.kuali.common.core.validate.annotation.IdiotProofImmutable; 19 import org.slf4j.Logger; 20 21 import com.google.common.base.Optional; 22 23 @IdiotProofImmutable 24 public final class S3FileSystem { 25 26 private static final Logger logger = newLogger(); 27 28 private final File basedir; 29 private final String bucket; 30 private final CommandLineService cli; 31 private final String encoding; 32 33 public void unmount() { 34 if (isMounted()) { 35 String mountPoint = getMountPoint(); 36 List<String> args = asList("umount", "-f", mountPoint); 37 info("unmount -> %s", mountPoint); 38 cli.execute("sudo", args); 39 } 40 } 41 42 public void mount() { 43 if (!isMounted()) { 44 String mountPoint = getMountPoint(); 45 List<String> args = asList(bucket, mountPoint); 46 info("mount -> s3fs %s %s", bucket, mountPoint); 47 cli.execute("s3fs", args); 48 } 49 } 50 51 private String getMountPoint() { 52 return basedir.getPath() + "/" + bucket; 53 } 54 55 private boolean isMounted() { 56 StringStreamConsumer consumer = new StringStreamConsumer(encoding); 57 ExecRequest request = ExecRequest.builder("mount").redirectOutput(consumer).build(); 58 cli.execute(request); 59 String token = getMountPoint(); 60 Optional<String> optional = consumer.getOutput(); 61 checkNotBlank(optional, "mount output"); 62 String output = optional.get(); 63 boolean mounted = output.contains(token); 64 return mounted; 65 } 66 67 private S3FileSystem(Builder builder) { 68 this.basedir = builder.basedir; 69 this.bucket = builder.bucket; 70 this.cli = builder.cli; 71 this.encoding = builder.encoding; 72 } 73 74 public static S3FileSystem build(File basedir, String bucket) throws IOException { 75 return builder().withBasedir(basedir).withBucket(bucket).build(); 76 } 77 78 public static Builder builder() { 79 return new Builder(); 80 } 81 82 public static class Builder extends ValidatingBuilder<S3FileSystem> { 83 84 private String bucket; 85 private File basedir; 86 private CommandLineService cli = new PlexusCLIService(); 87 private String encoding = UTF8; 88 89 public Builder withBasedir(File basedir) { 90 this.basedir = basedir; 91 return this; 92 } 93 94 public Builder withBucket(String bucket) { 95 this.bucket = bucket; 96 return this; 97 } 98 99 public Builder withCli(CommandLineService cli) { 100 this.cli = cli; 101 return this; 102 } 103 104 public Builder withEncoding(String encoding) { 105 this.encoding = encoding; 106 return this; 107 } 108 109 @Override 110 public S3FileSystem build() { 111 return validate(new S3FileSystem(this)); 112 } 113 } 114 115 public File getBasedir() { 116 return basedir; 117 } 118 119 public String getBucket() { 120 return bucket; 121 } 122 123 public CommandLineService getCli() { 124 return cli; 125 } 126 127 public String getEncoding() { 128 return encoding; 129 } 130 131 private void info(String msg, Object... args) { 132 logger.info((args == null || args.length == 0) ? msg : format(msg, args)); 133 } 134 135 }