package jp.aegif.nemaki.aws.tools.backup; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import org.apache.http.client.utils.URIUtils; import jp.aegif.nemaki.bjornloka.dump.*; import com.amazonaws.AmazonClientException; import com.amazonaws.AmazonServiceException; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.event.ProgressEvent; import com.amazonaws.event.ProgressListener; import com.amazonaws.regions.Region; import com.amazonaws.regions.Regions; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.model.PutObjectRequest; import com.amazonaws.services.s3.transfer.TransferManager; import com.amazonaws.services.s3.transfer.Upload; import org.json.*; import javax.ws.rs.client.*; import javax.ws.rs.core.*; public class BackupCouchDbToS3Util { static String DefaultCouchDbUrl = "http://localhost:5984/"; static String DefaultProfileName = "NemakiWare"; public void backup(String bucketName) { try { URI uri = new URI(DefaultCouchDbUrl); backup(bucketName, uri, DefaultProfileName, new String[0]); } catch (Exception ex) { } } public void backup(String bucketName, URI url) { backup(bucketName, url, DefaultProfileName, new String[0]); } public void backup(String bucketName, URI url, String profileName) { backup(bucketName, url, profileName, new String[0]); } public void backup(String bucketName, URI url, String profileName, String targets) { if (targets == null | targets == "") { backup(bucketName, url, profileName, new String[0]); } else { backup(bucketName, url, profileName, targets.split(",", -1)); } } public void backup(String bucketName, URI couchUrl, String profileName, String[] targets) { String[] targetDbs = targets; AmazonS3 s3client = new AmazonS3Client(new ProfileCredentialsProvider(profileName)); TransferManager tm = new TransferManager(s3client); try{ String uriScheme = couchUrl.getScheme(); if (targetDbs == null || targetDbs.length == 0) { URI targetRestURL = couchUrl; if (uriScheme.equals("file")) { try { targetRestURL = new URI(DefaultCouchDbUrl); } catch (URISyntaxException e) { } } List<String> list = getAllTargets(targetRestURL); targetDbs = (String[]) list.toArray(new String[0]); } for (String repositoryName : targetDbs) { System.out.println("[" + repositoryName + "] Backup started. "); if (repositoryName == null || repositoryName == "") continue; File file; try { if (uriScheme.equals("http") || uriScheme.equals("https")) { file = File.createTempFile(repositoryName, ".bk.dump"); String couchURI = couchUrl.toString(); DumpAction action = DumpAction.getInstance(couchURI, repositoryName, file, false); action.dump(); } else if (uriScheme.equals("file")) { couchUrl = couchUrl.resolve(repositoryName + ".couch"); file = new File(couchUrl); } else { System.out.printf("Error : Invalid scheme : %s \n", uriScheme); continue; } if (file.exists()) { uploadS3(tm, file, bucketName, repositoryName); } else { System.out.println("Error : Backup file not found"); System.out.println(file.getPath()); System.out.println(couchUrl.toString()); continue; } } catch (IOException e) { e.printStackTrace(); } } }finally{ tm.shutdownNow(true); } } public List<String> getAllTargets(URI couchUrl) { Client client = ClientBuilder.newClient(); String jsonArrayString = client.target(couchUrl).path("_all_dbs").request(MediaType.APPLICATION_JSON_TYPE) .get(String.class); JSONArray jsonArray = new JSONArray(jsonArrayString); List<String> list = new ArrayList<String>(); for (int i = 0; i < jsonArray.length(); i++) { list.add(jsonArray.getString(i)); } return list; } public void uploadS3(TransferManager tm, File file, String bucketName, String repositoryName) { try { PutObjectRequest request = new PutObjectRequest(bucketName, repositoryName, file); request.setGeneralProgressListener(new BackupFileUploadProgressListener(repositoryName)); System.out.println("[" + repositoryName + "] Upload started. "); Upload uploader = tm.upload(request); try { uploader.waitForCompletion(); System.out.println("[" + repositoryName + "] Upload complete. "); } catch (AmazonClientException amazonClientException) { System.out.println("[" + repositoryName + "] Unable to upload file, upload was aborted. "); amazonClientException.printStackTrace(); } catch (InterruptedException e) { System.out.println("[" + repositoryName + "] Unable to upload file, upload was interrupted. "); e.printStackTrace(); } uploader = null; } catch (AmazonServiceException ase) { System.out.println("Caught an AmazonServiceException, which " + "means your request made it " + "to Amazon S3, but was rejected with an error response" + " for some reason."); System.out.println("Error Message: " + ase.getMessage()); System.out.println("HTTP Status Code: " + ase.getStatusCode()); System.out.println("AWS Error Code: " + ase.getErrorCode()); System.out.println("Error Type: " + ase.getErrorType()); System.out.println("Request ID: " + ase.getRequestId()); } catch (AmazonClientException ace) { System.out.println("Caught an AmazonClientException, which " + "means the client encountered " + "an internal error while trying to " + "communicate with S3, " + "such as not being able to access the network."); System.out.println("Error Message: " + ace.getMessage()); } } }