1 package org.jgroups.tests;
2 
3 import org.jgroups.blocks.GridFile;
4 import org.jgroups.blocks.GridFilesystem;
5 import org.jgroups.blocks.ReplCache;
6 import org.jgroups.util.Util;
7 
8 import java.io.*;
9 import java.util.HashMap;
10 import java.util.Map;
11 
12 /**
13  * @author Bela Ban
14  * todo: regexp for file ls, rm, down and up
15  * todo: recursive up and down
16  */
17 public class GridFilesystemTest {
18     static final Map<String,Command> commands=new HashMap<String,Command>();
19     static String current_dir="/";
20     static final String HOME=System.getProperty("user.home");
21 
22     static {
23         commands.put("mkdir", new mkdir());
24         commands.put("ls",    new ls());
25         commands.put("cd",    new cd());
26         commands.put("pwd",   new pwd());
27         commands.put("rm",    new rm());
28         commands.put("up",    new up());
29         commands.put("down",  new down());
30     }
31 
main(String[] args)32     public static void main(String[] args) throws Exception {
33         String props="udp.xml";
34         String cluster_name="imfs-cluster";
35         String metadata_cluster_name="metadata-cluster";
36         short default_repl_count=1;
37         int default_chunk_size=4000;
38         GridFilesystem fs;
39 
40         for(int i=0; i < args.length; i++) {
41             if(args[i].equals("-props")) {
42                 props=args[++i];
43                 continue;
44             }
45             if(args[i].equals("-cluster_name")) {
46                 cluster_name=args[++i];
47                 continue;
48             }
49             if(args[i].equals("-metadata_cluster_name")) {
50                 metadata_cluster_name=args[++i];
51                 continue;
52             }
53             if(args[i].equals("-repl_count")) {
54                 default_repl_count=Short.parseShort(args[++i]);
55                 continue;
56             }
57             if(args[i].equals("-chunk_size")) {
58                 default_chunk_size=Integer.parseInt(args[++i]);
59                 continue;
60             }
61 
62             System.out.println("GridFilesystemTest [-props <JGroups config>] [-cluster_name <name>] " +
63                     "[-metadata_cluster_name <name>] [-repl_count <count>] [-chunk_size <size (bytes)>]");
64             return;
65         }
66 
67         ReplCache<String,byte[]> data=new ReplCache<String,byte[]>(props, cluster_name);
68         ReplCache<String, GridFile.Metadata> metadata=new ReplCache<String, GridFile.Metadata>(props, metadata_cluster_name);
69         data.start();
70         metadata.start();
71 
72         fs=new GridFilesystem(data, metadata, default_repl_count, default_chunk_size);
73         loop(fs);
74 
75         data.stop();
76         metadata.stop();
77     }
78 
loop(GridFilesystem fs)79     private static void loop(GridFilesystem fs) {
80         while(true) {
81             try {
82                 System.out.print("> ");
83                 String line=Util.readLine(System.in);
84                 if(!execute(fs, line))
85                     break;
86             }
87             catch(Throwable t) {
88                 t.printStackTrace();
89             }
90         }
91     }
92 
execute(GridFilesystem fs, String line)93     private static boolean execute(GridFilesystem fs, String line) {
94         String[] comps=parseCommandLine(line);
95         if(comps == null || comps.length == 0) {
96             help();
97             return true;
98         }
99         if(comps[0].equalsIgnoreCase("quit") || comps[0].equalsIgnoreCase("exit"))
100             return false;
101         if(comps[0].equalsIgnoreCase("help")) {
102             help();
103             return true;
104         }
105         Command cmd=commands.get(comps[0]);
106         if(cmd == null) {
107             System.err.println(comps[0] + " not known");
108             help();
109             return true;
110         }
111         String[] args=null;
112         if(comps.length > 1) {
113             args=new String[comps.length -1];
114             System.arraycopy(comps, 1, args, 0, args.length);
115         }
116         cmd.execute(fs, args);
117         return true;
118     }
119 
help()120     private static void help() {
121         StringBuilder sb=new StringBuilder("Valid commands:\nhelp\nquit\nexit\n");
122         for(Command cmd: commands.values()) {
123             String help=cmd.help();
124             if(help != null)
125                 sb.append(help).append("\n");
126         }
127         System.out.println(sb.toString());
128     }
129 
parseCommandLine(String line)130     private static String[] parseCommandLine(String line) {
131         if(line == null)
132             return null;
133         return line.trim().split(" ");
134     }
135 
136 
137     private static interface Command {
execute(GridFilesystem fs, String[] args)138         void execute(GridFilesystem fs, String[] args);
help()139         String help();
140     }
141 
142     private static class ls implements Command {
143 
execute(GridFilesystem fs, String[] args)144         public void execute(GridFilesystem fs, String[] args) {
145             String options=parseOptions(args);
146             boolean recursive=options.contains("R");
147             boolean detailed=options.contains("l");
148             String[] files=getNonOptions(args);
149             if(files == null || files.length == 0)
150                 files=new String[]{current_dir};
151             for(String str: files) {
152                 if(!str.startsWith(File.separator))
153                     str=current_dir + File.separator + str;
154                 File file=fs.getFile(str);
155                 if(!file.exists()) {
156                     System.err.println("File " + file + " doesn't exist");
157                     continue;
158                 }
159                 print(file, detailed, recursive, 0, file.isDirectory());
160             }
161         }
162 
help()163         public String help() {
164             return "ls [-lR] [dirs | files]";
165         }
166     }
167 
168     private static class mkdir implements Command {
169 
execute(GridFilesystem fs, String[] args)170         public void execute(GridFilesystem fs, String[] args) {
171             String options=parseOptions(args);
172             boolean recursive=options.contains("p");
173             String[] dir_names=getNonOptions(args);
174             if(dir_names == null || dir_names.length < 1) {
175                 System.err.println(help());
176                 return;
177             }
178             for(String dir: dir_names) {
179                 if(!dir.startsWith(File.separator))
180                     dir=current_dir + File.separator + dir;
181                 File file=fs.getFile(dir);
182                 boolean result;
183                 if(recursive)
184                     result=file.mkdirs();
185                 else
186                     result=file.mkdir();
187                 if(!result)
188                     System.err.println("failed creating " + dir);
189             }
190         }
191 
help()192         public String help() {
193             return "mkdir [-p] dirs";
194         }
195     }
196 
197 
198     private static class rm implements Command {
199 
execute(GridFilesystem fs, String[] args)200         public void execute(GridFilesystem fs, String[] args) {
201             String options=parseOptions(args);
202             boolean recursive=options.contains("r");
203             String[] dir_names=getNonOptions(args);
204             if(dir_names == null || dir_names.length < 1) {
205                 System.err.println(help());
206                 return;
207             }
208             for(String dir: dir_names) {
209                 if(!dir.startsWith(File.separator))
210                     dir=current_dir.equals(File.separator)? current_dir + dir : current_dir + File.separator + dir;
211                 File file=fs.getFile(dir);
212                 if(!file.exists()) {
213                     System.err.println(file.getName() + " doesn't exist");
214                     return;
215                 }
216                 if(file.isFile()) {
217                     if(!file.delete())
218                         System.err.println("cannot remove " + file.getName());
219                     return;
220                 }
221 
222                 if(!recursive) {
223                     if(!file.delete())
224                         System.err.println("cannot remove " + file.getName() + ": is a directory");
225                 }
226                 else {
227                     if(!delete(file)) { // recursive delete
228                         System.err.println("recursive removal of " + file.getName() + " failed");
229                     }
230                 }
231             }
232         }
233 
help()234         public String help() {
235             return "rm [-fr] <files or dirs>";
236         }
237     }
238 
239 
240     private static class cd implements Command {
241 
execute(GridFilesystem fs, String[] args)242         public void execute(GridFilesystem fs, String[] args) {
243             String[] tmp=getNonOptions(args);
244             String target_dir="~";
245             if(tmp != null && tmp.length == 1)
246                 target_dir=tmp[0];
247 
248             if(target_dir.equals(".."))
249                 target_dir=new File(current_dir).getParent();
250             if(target_dir.contains("~") && HOME != null)
251                 target_dir=target_dir.replace("~", HOME);
252             if(!target_dir.trim().startsWith(File.separator)) {
253                 target_dir=current_dir.equals(File.separator)?
254                         current_dir + target_dir :
255                         current_dir + File.separator + target_dir;
256             }
257             File dir=fs.getFile(target_dir);
258             if(!dir.exists()) {
259                 System.err.println("Directory " + target_dir + " doesn't exist");
260             }
261             else
262                 current_dir=target_dir;
263         }
264 
help()265         public String help() {
266             return "cd [dir]";
267         }
268     }
269 
270     private static class pwd implements Command {
271 
execute(GridFilesystem fs, String[] args)272         public void execute(GridFilesystem fs, String[] args) {
273             System.out.println(current_dir);
274         }
275 
help()276         public String help() {
277             return "pwd";
278         }
279     }
280 
281 
282     private static class up implements Command {
283 
execute(GridFilesystem fs, String[] args)284         public void execute(GridFilesystem fs, String[] args) {
285             String   options=parseOptions(args);
286             String[] real_args=getNonOptions(args);
287             boolean  overwrite=options.contains("f");
288 
289             if(real_args.length == 0) {
290                 System.err.println(help());
291                 return;
292             }
293 
294             String local_path=real_args[0], grid_path=real_args.length > 1? real_args[1] : null;
295             if(HOME != null && local_path.contains("~"))
296                 local_path=local_path.replace("~", HOME);
297             String target_path=grid_path != null? grid_path : local_path;
298             if(target_path.contains("~"))
299                 target_path=target_path.replace("~", HOME);
300             if(target_path.equals("."))
301                 target_path=current_dir;
302 
303             File target=fs.getFile(target_path);
304             if(!overwrite && target.exists() && target.isFile()) {
305                 System.err.println("grid file " + target_path + " already exists; use -f to force overwrite");
306                 return;
307             }
308 
309             if(target.exists() && target.isDirectory()) {
310                 String[] comps=Util.components(local_path, File.separator);
311                 String filename=comps[comps.length - 1];
312                 target_path=target_path + (target_path.equals(File.separator)? filename : File.separator + filename);
313             }
314 
315             FileInputStream in=null;
316             OutputStream out=null;
317             try {
318                 in=new FileInputStream(local_path);
319                 File out_file=fs.getFile(target_path);
320                 if(out_file.exists() && out_file.isDirectory()) {
321                     System.err.println("target " + target_path + " is a directory");
322                     return;
323                 }
324                 if(out_file.exists() && out_file.isFile() && overwrite) {
325                     if(out_file instanceof GridFile)
326                         ((GridFile)out_file).delete(true);
327                     else
328                         out_file.delete();
329                 }
330 
331                 out=fs.getOutput((GridFile)out_file);
332                 byte[] buf=new byte[50000];
333                 int len, total=0;
334                 while((len=in.read(buf, 0, buf.length)) != -1) {
335                     out.write(buf, 0, len);
336                     total+=len;
337                 }
338                 System.out.println("uploaded " + local_path + " to " + target_path + " (" + total + " bytes)");
339             }
340             catch(FileNotFoundException e) {
341                 System.err.println("local file " + local_path + " not found");
342             }
343             catch(IOException e) {
344                 System.err.println("cannot create " + target_path);
345             }
346             finally {
347                 Util.close(in);
348                 Util.close(out);
349             }
350         }
351 
help()352         public String help() {
353             return "up [-f] <local path> [<grid path>]";
354         }
355     }
356 
357 
358     private static class down implements Command {
359 
execute(GridFilesystem fs, String[] args)360         public void execute(GridFilesystem fs, String[] args) {
361             String   options=parseOptions(args);
362             String[] real_args=getNonOptions(args);
363             boolean  overwrite=options.contains("f");
364 
365             if(real_args.length == 0) {
366                 System.err.println(help());
367                 return;
368             }
369 
370             String grid_path=real_args[0], local_path=real_args.length > 1? real_args[1] : null;
371             if(HOME != null && grid_path.contains("~"))
372                 grid_path=grid_path.replace("~", HOME);
373             String target_path=local_path != null? local_path : grid_path;
374             if(target_path.contains("~"))
375                 target_path=target_path.replace("~", HOME);
376             if(target_path.equals("."))
377                 target_path=System.getProperty("user.dir");
378 
379             File target=new File(target_path);
380             if(!overwrite && target.exists() && target.isFile()) {
381                 System.err.println("grid file " + target_path + " already exists; use -f to force overwrite");
382                 return;
383             }
384 
385             if(target.exists() && target.isDirectory()) {
386                 String[] comps=Util.components(grid_path, File.separator);
387                 String filename=comps[comps.length - 1];
388                 target_path=target_path + (target_path.endsWith(File.separator)? filename : File.separator + filename);
389             }
390 
391             InputStream in=null;
392             FileOutputStream out=null;
393             try {
394                 in=fs.getInput(grid_path);
395                 File out_file=new File(target_path);
396                 if(out_file.exists() && out_file.isDirectory()) {
397                     System.err.println("target " + target_path + " is a directory");
398                     return;
399                 }
400                 out=new FileOutputStream(out_file);
401                 byte[] buf=new byte[50000];
402                 int len, total=0;
403                 while((len=in.read(buf, 0, buf.length)) != -1) {
404                     out.write(buf, 0, len);
405                     total+=len;
406                 }
407                 System.out.println("downloaded " + local_path + " to " + target_path + " (" + total + " bytes)");
408             }
409             catch(FileNotFoundException e) {
410                 System.err.println("local file " + local_path + " not found");
411             }
412             catch(IOException e) {
413                 System.err.println("cannot create " + target_path);
414             }
415             finally {
416                 Util.close(in);
417                 Util.close(out);
418             }
419         }
420 
help()421         public String help() {
422             return "down [-f] <grid path> [<local path>]";
423         }
424     }
425 
426 
parseOptions(String[] args)427     private static String parseOptions(String[] args) {
428         StringBuilder sb=new StringBuilder();
429         if(args == null)
430             return "";
431         for(String str: args) {
432             if(str.startsWith("-"))
433                 sb.append(str.substring(1));
434         }
435         return sb.toString();
436     }
437 
getNonOptions(String[] args)438     private static String[] getNonOptions(String[] args) {
439         if(args == null)
440             return null;
441         int cnt=0;
442         for(String str: args)
443             if(!str.startsWith("-"))
444                 cnt++;
445         String[] retval=new String[cnt];
446         cnt=0;
447         for(String str: args)
448             if(!str.startsWith("-"))
449                 retval[cnt++]=str;
450         return retval;
451     }
452 
delete(File dir)453     private static boolean delete(File dir) {
454         boolean retval=true;
455         if(dir == null)
456             return false;
457         File[] files=dir.listFiles();
458         if(files != null) {
459             for(File file: files) {
460                 if(!delete(file))
461                     retval=false;
462             }
463         }
464         boolean rc=dir instanceof GridFile? ((GridFile)dir).delete(true) : dir.delete();
465         if(!rc)
466             retval=false;
467         return retval;
468     }
469 
print(File file, boolean details, boolean recursive, int indent, boolean exclude_self)470     private static void print(File file, boolean details, boolean recursive, int indent, boolean exclude_self) {
471         if(file.isDirectory()) {
472             if(!exclude_self)
473                 System.out.print(print(file, details, indent));
474             File[] children=file.listFiles();
475             for(File child: children) {
476                 if(!recursive)
477                     System.out.print(print(child, details, indent));
478                 else {
479                     print(child, details, recursive, indent +4, false);
480                 }
481             }
482             if(children.length > 0)
483                 System.out.println("");
484         }
485         else {
486             String tmp=print(file, details, indent);
487             System.out.print(tmp);
488         }
489     }
490 
print(File file, boolean details, int indent)491     private static String print(File file, boolean details, int indent) {
492         StringBuilder sb=new StringBuilder();
493         if(file.isDirectory()) {
494             if(details)
495                 sb.append(indent(indent));
496             sb.append(file.getName()).append("/");
497         }
498         else {
499             if(details)
500                 sb.append(indent(indent));
501             sb.append(file.getName());
502             if(details) {
503                 sb.append(" " + Util.printBytes(file.length()));
504                 if(file instanceof GridFile)
505                     sb.append(", chunk_sise=" + ((GridFile)file).getChunkSize());
506             }
507 
508         }
509         sb.append(details? '\n' : ' ');
510         return sb.toString();
511     }
512 
indent(int num)513     private static String indent(int num) {
514         StringBuilder sb=new StringBuilder();
515         for(int i=0; i < num; i++)
516             sb.append(' ');
517         return sb.toString();
518     }
519 
520 
521 }