1 package edu.virginia.lib.ole.akubra.utilities;
2
3 import java.io.File;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.OutputStream;
7 import java.net.URI;
8 import java.net.URLDecoder;
9 import java.util.Iterator;
10 import java.util.concurrent.ExecutorService;
11 import java.util.concurrent.Executors;
12
13 import org.akubraproject.Blob;
14 import org.akubraproject.BlobStore;
15 import org.akubraproject.BlobStoreConnection;
16 import org.akubraproject.fs.FSBlobStore;
17 import org.akubraproject.map.IdMapper;
18 import org.akubraproject.map.IdMappingBlobStore;
19 import org.apache.commons.cli.CommandLine;
20 import org.apache.commons.cli.CommandLineParser;
21 import org.apache.commons.cli.GnuParser;
22 import org.apache.commons.cli.HelpFormatter;
23 import org.apache.commons.cli.Option;
24 import org.apache.commons.cli.Options;
25 import org.apache.commons.cli.ParseException;
26 import org.apache.commons.io.IOUtils;
27
28 import edu.virginia.lib.ole.akubra.Constants;
29 import edu.virginia.lib.ole.akubra.FilePrefixMapper;
30
31 public class FSBlobStoreSplitter {
32
33 private class FSBlobStoreSplitterImpl {
34
35 private BlobStore original, left, right;
36
37 private ExecutorService threadpool = Executors.newFixedThreadPool(1);
38
39 private boolean clean = true;
40
41 public FSBlobStoreSplitterImpl(BlobStore original, BlobStore left,
42 BlobStore right) {
43 this.original = original;
44 this.left = left;
45 this.right = right;
46 }
47
48 public void split() throws UnsupportedOperationException, IOException {
49 BlobStoreConnection orig = original.openConnection(null, null);
50 BlobStoreConnection l = left.openConnection(null, null);
51 BlobStoreConnection r = right.openConnection(null, null);
52 URI blobId = null;
53 Iterator<URI> blobList = orig.listBlobIds(null);
54 while (blobList.hasNext()) {
55 blobId = blobList.next();
56 print("Entering blobList.hasNext()");
57
58
59
60 String blobIdString = URLDecoder.decode(blobId.toString(),
61 "UTF-8");
62 print("Using blobIdString: " + blobIdString);
63 blobId = URI.create(blobIdString);
64 String newBlobIdString = blobIdString
65 .substring(Constants.CHUNK + 1);
66 print("Using newBlobIdString: " + newBlobIdString);
67 Short front = Short.parseShort(
68 (blobIdString.substring(0, Constants.CHUNK)), 2);
69 print("Using front: " + front);
70 URI newBlobId = URI.create(newBlobIdString);
71
72 Blob inBlob = orig.getBlob(blobId, null);
73 if (front % 2 == 0) {
74 threadpool.execute(new copyBlob(inBlob, l, newBlobId));
75 } else {
76 threadpool.execute(new copyBlob(inBlob, r, newBlobId));
77 }
78 if (!clean) {
79 print("Failed to finish split!");
80 System.exit(1);
81 }
82 }
83 threadpool.shutdown();
84 }
85
86 private class copyBlob implements Runnable {
87 private final Blob inBlob;
88 private final BlobStoreConnection target;
89 private final URI newBlobId;
90
91 copyBlob(Blob inBlob, BlobStoreConnection target, URI newBlobId) {
92 this.inBlob = inBlob;
93 this.target = target;
94 this.newBlobId = newBlobId;
95 }
96
97 public void run() {
98 print("Copying inBlob " + inBlob.getId() + " to target store "
99 + target.getBlobStore().getId() + " under new URI "
100 + newBlobId);
101 InputStream in;
102 OutputStream out;
103 try {
104 in = inBlob.openInputStream();
105 out = target.getBlob(newBlobId, null).openOutputStream(
106 inBlob.getSize(), true);
107 IOUtils.copy(in, out);
108 out.close();
109 out = null;
110 in.close();
111 in = null;
112 } catch (Exception e) {
113 clean = false;
114 e.printStackTrace();
115 }
116
117 }
118
119 }
120
121 private void print(String s) {
122 System.out.println(s);
123 }
124 }
125
126 public static void main(String[] args) {
127
128 Options options = new Options();
129 options.addOption(new Option("r", "right", true,
130 "Right-hand output BlobStore filepath (required)"));
131 options.addOption(new Option("l", "left", true,
132 "Left-hand output BlobStore filepath (required)"));
133 options.addOption(new Option("o", "original", true,
134 "Original (input) BlobStore filepath (required)"));
135 options.addOption(new Option("h", "help", false,
136 "Get this help"));
137
138 CommandLineParser parser = new GnuParser();
139 HelpFormatter formatter = new HelpFormatter();
140 CommandLine cmd = null;
141 try {
142 cmd = parser.parse( options, args);
143 } catch (ParseException e1) {
144 System.out.println("Failed to parse options: ");
145 e1.printStackTrace();
146 }
147
148
149 if (cmd.hasOption("h")) {
150 formatter.printHelp( "TwoStore BlobSplitter", options, true );
151 System.exit(0);
152 }
153 if (!cmd.hasOption("r")) {
154 System.out.println("Missing right-hand output BlobStore filepath!");
155 formatter.printHelp( "TwoStore BlobSplitter", options, true );
156 System.exit(1);
157 }
158 if (!cmd.hasOption("l")) {
159 System.out.println("Missing left-hand output BlobStore filepath!");
160 formatter.printHelp( "TwoStore BlobSplitter", options, true );
161 System.exit(1);
162 }
163 if (!cmd.hasOption("o")) {
164 System.out.println("Missing original (input) BlobStore filepath!");
165 formatter.printHelp( "TwoStore BlobSplitter", options, true );
166 System.exit(1);
167 }
168
169 String original_location = cmd.getOptionValue("o");
170 String left_location = cmd.getOptionValue("l");
171 String right_location = cmd.getOptionValue("r");
172
173 BlobStore fsoriginal = new FSBlobStore(URI.create("fsoriginal"),
174 new File(original_location));
175 BlobStore fsleft = new FSBlobStore(URI.create("fsleft"), new File(
176 left_location));
177 BlobStore fsright = new FSBlobStore(URI.create("fsright"), new File(
178 right_location));
179
180 IdMapper fileprefixmapper = new FilePrefixMapper();
181
182 BlobStore original = new IdMappingBlobStore(URI.create("original"),
183 fsoriginal, fileprefixmapper);
184 BlobStore left = new IdMappingBlobStore(URI.create("left"), fsleft,
185 fileprefixmapper);
186 BlobStore right = new IdMappingBlobStore(URI.create("right"), fsright,
187 fileprefixmapper);
188
189 try {
190 new FSBlobStoreSplitter().new FSBlobStoreSplitterImpl(original,
191 left, right).split();
192 } catch (Exception e) {
193 e.printStackTrace();
194 }
195 }
196 }