package org.xmlsh.aws.clients;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.KeyPair;
import java.security.Security;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import javax.xml.stream.XMLStreamException;
import net.sf.saxon.s9api.SaxonApiException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMReader;
import org.xmlsh.aws.util.AWSClient;
import org.xmlsh.aws.util.AWSCommandCredentialsProviderChain;
import org.xmlsh.aws.util.AWSS3Command;
import org.xmlsh.aws.util.S3Path;
import org.xmlsh.core.CoreException;
import org.xmlsh.core.InputPort;
import org.xmlsh.core.Options;
import org.xmlsh.core.XValue;
import org.xmlsh.sh.shell.SerializeOpts;
import org.xmlsh.sh.shell.Shell;
import org.xmlsh.util.Util;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3EncryptionClient;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.CryptoConfiguration;
import com.amazonaws.services.s3.model.EncryptionMaterials;
import com.amazonaws.services.s3.model.GetBucketAclRequest;
import com.amazonaws.services.s3.model.StaticEncryptionMaterialsProvider;
import com.amazonaws.services.s3.transfer.TransferManager;
public final class S3Client extends AWSClient<AmazonS3Client> {
private TransferManager tm = null;
private int mThreads = 10 ;
protected ThreadPoolExecutor createDefaultExecutorService() {
ThreadFactory threadFactory = new ThreadFactory() {
private int threadCount = 1;
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setName("s3-transfer-manager-worker-" + threadCount++);
return thread;
}
};
return (ThreadPoolExecutor)Executors.newFixedThreadPool(mThreads, threadFactory);
}
public S3Client(Shell shell,Options opts) throws UnsupportedEncodingException, IOException, CoreException {
super( new AmazonS3Client(new AWSCommandCredentialsProviderChain( shell , opts ) ));
if( opts.hasOpt("threads"))
mThreads = opts.getOptInt("threads", mThreads);
ClientConfiguration clientConfig = new ClientConfiguration();
if( opts.hasOpt("crypt")){
synchronized( AWSS3Command.class ){
if( Security.getProperty(BouncyCastleProvider.PROVIDER_NAME) == null )
Security.addProvider(new BouncyCastleProvider());
}
XValue sKeypair = opts.getOptValueRequired("keypair");
KeyPair keyPair = (KeyPair) readPEM(shell.getEnv().getInput(sKeypair), shell.getSerializeOpts(opts));
mClient = new AmazonS3EncryptionClient(
new AWSCommandCredentialsProviderChain( shell , opts ) ,
new StaticEncryptionMaterialsProvider(
new EncryptionMaterials( keyPair )),
clientConfig , new CryptoConfiguration()
);
} else
mClient = new AmazonS3Client(
new AWSCommandCredentialsProviderChain( shell, opts ) ,
clientConfig
);
setEndpoint(shell,opts);
setRegion(shell,opts);
}
private Object readPEM(InputPort in, SerializeOpts sopts ) throws CoreException, IOException {
try ( PEMReader reader = new PEMReader( in.asReader( sopts )) ){
Object obj = reader.readObject();
return obj;
}
}
public S3Path getS3Path( String bucket , String key )
{
return new S3Path( bucket , key );
}
public CannedAccessControlList getAcl(String acl) {
for(CannedAccessControlList c : CannedAccessControlList.values())
if( c.toString().equals(acl))
return c;
return null ;
}
public int setAcl(S3Path src, String acl) throws CoreException, IOException,
XMLStreamException, SaxonApiException {
mClient.setObjectAcl(src.getBucket(),src.getKey(), getAcl(acl));
return 0;
}
public TransferManager getTransferManager() {
if( tm == null)
tm = new TransferManager( mClient , createDefaultExecutorService() );
return tm;
}
public void shutdownTransferManager() {
if( tm != null)
tm.shutdownNow();
}
}