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 }