/* ************************************************************************ # # DivConq # # http://divconq.com/ # # Copyright: # Copyright 2014 eTimeline, LLC. All rights reserved. # # License: # See the license.txt file in the project's top-level directory for details. # # Authors: # * Andy White # ************************************************************************ */ package divconq.interchange.s3; public class S3Driver { /*extends RecordStruct implements IFileStoreDriver { protected AmazonS3Client s3 = null; protected IMimeProvider mimes = null; @Override public void setMimeProvider(IMimeProvider v) { this.mimes = v; } public S3Driver() { this.setField("Scanner", new S3Scanner(this)); this.setField("RootFolder", "."); } @Override protected void doCopy(Struct n) { super.doCopy(n); } @Override public Struct deepCopy() { S3Driver cp = new S3Driver(); this.doCopy(cp); return cp; } @Override public void dispose() { this.close(null); super.dispose(); } /* @Override public void toBuilder(ICompositeBuilder builder) throws BuilderStateException { builder.startRecord(); for (FieldStruct f : this.fields.values()) f.toBuilder(builder); // TODO add in FS specific fields builder.endRecord(); } @Override public Struct select(PathPart... path) { if (path.length > 0) { PathPart part = path[0]; if (part.isField()) { String fld = part.getField(); if ("Scanner".equals(fld)) return this.search; } } return super.select(path); } * / @Override public void connect(RecordStruct params, OperationCallback callback) { this.copyFields(params); // TODO clean and start new this.channels.dispose() this.s3 = new AmazonS3Client(new AWSCredentials() { @Override public String getAWSSecretKey() { return S3Driver.this.getFieldAsString("AwsSecretKey"); } @Override public String getAWSAccessKeyId() { return S3Driver.this.getFieldAsString("AwsAccessKey"); } }); System.out.println("cwd: " + this.getFieldAsString("RootFolder")); /* for (Bucket bucket : this.s3.listBuckets()) System.out.println(" - " + bucket.getName()); System.out.println(); System.out.println("Listing objects"); ObjectListing objectListing = s3.listObjects(new ListObjectsRequest() .withBucketName("chron-present")); for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) { System.out.println(" - " + objectSummary.getKey() + " " + "(size = " + objectSummary.getSize() + ")"); } System.out.println(); * / if (callback == null) return; callback.completed(); } @Override public void close(OperationCallback callback) { if (callback == null) return; callback.completed(); } @Override public void operation(final StackEntry stack, final XElement codeEl) { if ("Connect".equals(codeEl.getName())) { this.connect(null, new OperationCallback() { @Override public void callback() { stack.resume(); } }); return; } if ("Close".equals(codeEl.getName())) { this.close(new OperationCallback() { @Override public void callback() { stack.resume(); } }); return; } if ("Put".equals(codeEl.getName())) { // TODO integrate with put method below Struct src = stack.refFromElement(codeEl, "Source"); if (!(src instanceof IFileStoreFile) && ! (src instanceof RecordStruct)) { // TODO log wrong type stack.resume(); return; } boolean relative = stack.boolFromElement(codeEl, "Relative", true); this.put((IFileStoreFile)src, relative, new FuncCallback<IFileStoreFile>() { @Override public void callback() { // TODO check errors String handle = stack.stringFromElement(codeEl, "Handle"); if (handle != null) stack.addVariable(handle, (Struct) this.getResult()); stack.resume(); } }); return; } if ("PutAll".equals(codeEl.getName())) { // TODO integrate with put method below Struct src = stack.refFromElement(codeEl, "Source"); if (src == null) { // TODO log missing stack.resume(); return; } if (!(src instanceof IItemCollection)) { // TODO log wrong type stack.resume(); return; } boolean relative = stack.boolFromElement(codeEl, "Relative", true); this.putAll((IItemCollection)src, relative, new OperationCallback() { @Override public void callback() { // TODO check errors System.out.println("done"); stack.resume(); } }); return; } /* if ("GetInfo".equals(codeEl.getName())) { String path = stack.stringFromElement(codeEl, "Path"); if (StringUtil.isEmpty(path)) { // TODO log missing stack.resume(); return; } String handle = stack.stringFromElement(codeEl, "Handle"); if (handle != null) stack.addVariable(handle, new SftpFile(SftpDriver.this, new RecordStruct(new FieldStruct("Path", path)))); stack.resume(); return; } if ("Put".equals(codeEl.getName())) { Struct src = stack.refFromElement(codeEl, "Source"); if (src == null) { // TODO log missing stack.resume(); return; } if (!(src instanceof IFileStoreFile) && ! (src instanceof RecordStruct)) { // TODO log wrong type stack.resume(); return; } RecordStruct rsrc = (RecordStruct)src; final IFileStoreFile ssrc = (IFileStoreFile)src; boolean relative = stack.boolFromElement(codeEl, "Relative", true); String cwd = this.getFieldAsString("RootFolder"); String dfilepath = cwd + "/" + (relative ? rsrc.getFieldAsString("Path") : rsrc.getFieldAsString("Name")); System.out.println("copied to: " + dfilepath); final File dest = new File(dfilepath); dest.getParentFile().mkdirs(); try { final FileOutputStream out = new FileOutputStream(dest); ssrc.copyTo(out, new OperationCallback() { @Override public void callback() { // TODO improve, check abort, etc try { out.close(); } catch (IOException x) { } String handle = stack.stringFromElement(codeEl, "Handle"); if (handle != null) stack.addVariable(handle, new SftpFile(SftpDriver.this, dest)); stack.resume(); } }); return; } catch (Exception x) { // TODO //ssrc.abort(); } stack.resume(); return; } */ /* if ("ChangeDirectory".equals(code.getName())) { String path = stack.stringFromElement(code, "Path"); if (StringUtil.isEmpty(path)) { // TODO log stack.resume(); return; } this.cwd = new File(path); stack.resume(); return; } if ("ScanFilter".equals(code.getName())) { String path = stack.stringFromElement(code, "Path"); ... if (StringUtil.isEmpty(path)) { // TODO log stack.resume(); return; } this.cwd = new File(path); stack.resume(); return; } * / //System.out.println("fs operation: " + code); super.operation(stack, codeEl); } @Override public IFileStoreFile getFile(RecordStruct file) { return new S3File(this, file); } @Override public void getFileDetail(String path, FuncCallback<IFileStoreFile> callback) { // TODO Auto-generated method stub } @Override public void getRootFolder(FuncCallback<String> callback) { // TODO Auto-generated method stub } @Override public void setRootFolder(String path, OperationCallback callback) { // TODO Auto-generated method stub } @Override public void addFolder(String path, OperationCallback callback) { // TODO Auto-generated method stub } @Override public void removeFolder(String path, OperationCallback callback) { // TODO Auto-generated method stub } @Override public void queryFeatures(FuncCallback<RecordStruct> callback) { // TODO Auto-generated method stub } @Override public void customCommand(RecordStruct params, FuncCallback<RecordStruct> callback) { // TODO Auto-generated method stub } @Override public IFileStoreScanner getScanner() { // TODO Auto-generated method stub return null; } @Override public void getFolderListing(String path, FuncCallback<List<IFileStoreFile>> callback) { // TODO Auto-generated method stub //this.s3.listObjects(new ListObjectsRequest(bucketName, prefix, marker, delimiter, maxKeys)); } @Override public void getFolderListing2(String path, FuncCallback<ListStruct> callback) { // TODO Auto-generated method stub } @Override public void put(final IFileStoreFile source, boolean relative, final FuncCallback<IFileStoreFile> callback) { if (source == null) { // TODO log missing callback.completed(); return; } if (! (source instanceof RecordStruct)) { // TODO log wrong type callback.completed(); return; } final RecordStruct rsrc = (RecordStruct)source; String cwd = this.getFieldAsString("RootFolder"); final String dfilepath = cwd + "/" + (relative ? rsrc.getFieldAsString("Path") : rsrc.getFieldAsString("Name")); source.getInputStream(new FuncCallback<InputStream>() { @Override public void callback() { // TODO check errors final InputStream in = this.getResult(); ObjectMetadata md = new ObjectMetadata(); md.setContentLength(source.getSize()); // rsrc.getFieldAsInteger("Size")); // TODO other meta data too? // TODO missing stuff!!! S3Driver.this.s3.putObject(new PutObjectRequest(S3Driver.this.getFieldAsString("Bucket"), dfilepath, in, md)); callback.setResult(new S3File(S3Driver.this, rsrc)); callback.callback(); /* S3Driver.this.getChannel(new FuncCallback<ChannelSftp>() { @Override public void callback() { ChannelSftp channel = this.getResult(); try { System.out.println("copied to sftp: " + dfilepath); // TODO mkdirs // dest.getParentFile().mkdirs(); channel.mkdir(dfileparent); channel.put(in, dfilepath); @SuppressWarnings("rawtypes") Vector flist = channel.ls(dfilepath); if (flist.size() < 1) { // TODO log } else { LsEntry entry = (LsEntry)flist.get(0); callback.setResult(new S3File(S3Driver.this, entry, dfilepath)); } callback.completed(); } catch (Exception x) { // TODO //ssrc.abort(); callback.completed(); } finally { S3Driver.this.releaseChannel(channel); } } }); * / } }); } @Override public void put(InputStream in, long size, final IFileStoreFile dest, boolean relative, final OperationCallback callback) { this.put(in, size, dest, relative, null, callback); } public void put(InputStream in, long size, final IFileStoreFile dest, boolean relative, String attachmentname, final OperationCallback callback) { if (in == null) { // TODO log missing callback.completed(); return; } if (dest == null) { // TODO log missing callback.completed(); return; } if (! (dest instanceof RecordStruct)) { // TODO log wrong type callback.completed(); return; } final RecordStruct rsrc = (RecordStruct)dest; String cwd = this.getFieldAsString("RootFolder"); int pos = cwd.indexOf('/', 1); String bucket = cwd.substring(1, pos); cwd = cwd.substring(pos + 1); final String dfilepath = cwd + "/" + (relative ? rsrc.getFieldAsString("Path") : rsrc.getFieldAsString("Name")); // TODO check that path does not dip below working directory via .. File temp = null; // TODO error checking try { // if size is not known then save to temp file first if (size == -1) { temp = File.createTempFile(UUID.randomUUID().toString(), null); FileOutputStream fos = new FileOutputStream(temp); IOUtils.copy(in, fos); IOUtils.closeQuietly(fos); temp.deleteOnExit(); in = new FileInputStream(temp); size = temp.length(); } ObjectMetadata md = new ObjectMetadata(); //md.addUserMetadata("Modified", value); md.setContentLength(size); // TODO store other attributes too? if (this.mimes != null) md.setContentType(this.mimes.getMimeForExt(FilenameUtils.getExtension(dfilepath))); if (StringUtil.isNotEmpty(attachmentname)) md.setContentDisposition("attachment; filename=\"" + NetUtil.urlEncodeUTF8(attachmentname) + "\""); this.s3.putObject(new PutObjectRequest(bucket, dfilepath, in, md)); // TODO change before open source // TODO get permissions from file AccessControlList acl = new AccessControlList(); acl.setOwner(new Owner("151f1537f17624dca8ad737bf316bfd5f15bede15d10b9ffcf6073d8c8419025", "LightOfGadrel")); acl.grantPermission(GroupGrantee.AllUsers, Permission.Read); this.s3.setObjectAcl(bucket, dfilepath, acl); if (temp != null) temp.delete(); } catch (Exception x) { // TODO log error System.out.println("Error uploading to S3: " + x); } callback.completed(); } @Override public void putAll(IItemCollection files, boolean relative, OperationCallback callback) { // TODO Auto-generated method stub } */ }