/*******************************************************************************
* Copyright 2014 Miami-Dade County
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package org.sharegov.cirm.utils;
import java.util.List;
import mjson.Json;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.semanticweb.owlapi.model.OWLNamedIndividual;
import org.sharegov.cirm.CirmTransactionEvent;
import org.sharegov.cirm.CirmTransactionListener;
import org.sharegov.cirm.ConfigSet;
import org.sharegov.cirm.OWL;
/**
* Transaction listener that removes attachments (files or images) after a transaction success from AWS S3 (Also accepts but ignores legacy paths).<br>
* Legacy file based attachments are detected, will appear to the user to be successfully deleted, however, we don't actually delete the file from the server,
* but log a warning message instead. <br>
* <br>
* Suggested usage:<br>
* Create and add one object of this class if and only if hasRemovedAttachment json property coming in a service request json is a non empty array.<br>
* <br>
* @author David Wong, Thomas Hilpold
*
*/
public class RemoveAttachmentsOnTxSuccessListener implements CirmTransactionListener
{
final List<Json> hasRemovedAttachmentList;
public RemoveAttachmentsOnTxSuccessListener(final List<Json> hasRemovedAttachmentList) {
if (hasRemovedAttachmentList == null) throw new IllegalArgumentException("hasRemovedAttachmentList was null");
this.hasRemovedAttachmentList = hasRemovedAttachmentList;
}
@Override
public void transactionStateChanged(CirmTransactionEvent e)
{
if (e.isSucceeded()) {
if (!hasRemovedAttachmentList.isEmpty()) {
ThreadLocalStopwatch.now("START RemoveAttachmentsOnTxSuccessListener removing " + hasRemovedAttachmentList.size() + " attachments");
ThreadLocalStopwatch.getWatch().time("RemoveAttachmentsOnTxSuccessListener removing " + hasRemovedAttachmentList.size());
try {
deleteAttachments();
} catch (Exception ex) {
ThreadLocalStopwatch.error("Error: RemoveAttachmentsOnTxSuccessListener failed while deleting attachments. Stack trace to follow.");
ex.printStackTrace();
}
ThreadLocalStopwatch.now("END RemoveAttachmentsOnTxSuccessListener removing " + hasRemovedAttachmentList.size() + " attachments");
}
}
}
/**
* Deletes all images given by hasRemovedAttachmentList property from ASW, but also accepts legacy File paths.
*/
void deleteAttachments() {
String file;
for (Json attachment : hasRemovedAttachmentList) {
file = attachment.toString();
if(file.contains("aws") && file.contains("s3")) {
deleteFromAWS(file);
} else {
deleteFromFile(file);
}
}
}
/**
* Should delete a file from a location on disc, however this is not implemented.
* We print a warning message instead.
*
* @param filepath a local or remote windows file path
*/
void deleteFromFile(String filepath) {
ThreadLocalStopwatch.error("WARNING: RemoveAttachmentsOnTxSuccessListener: Deleting legacy image not implemented, but attempted with: " + filepath + " ");
// File newF = new File(filepath);
// boolean deleteStatus = newF.delete();
// if (deleteStatus == false) {
// throw new RuntimeException("Unable to delete file '"
// + filepath.toString() + "' from Images folder.");
// }
}
/**
* Deletes a file using AWS S3 middleware services as specified in config property UploadConfig.
*
* @param fileLocationUrl an AWS S3 location
*/
void deleteFromAWS(String fileLocationUrl) {
OWLNamedIndividual ind = ConfigSet.getInstance().get("UploadConfig");
String deleteServiceUrl = OWL.dataProperty(ind, "hasUrl").getLiteral();
deleteServiceUrl = deleteServiceUrl + "delete" + "/";
String deleteFileUrl;
try {
String[] tokens = fileLocationUrl.split("/");
String id = tokens[4];
id = id.replace("\"", "");
deleteFileUrl = deleteServiceUrl + id;
HttpClient client = new HttpClient();
DeleteMethod delete = new DeleteMethod(deleteFileUrl);
int statusCode = client.executeMethod(delete);
if (statusCode != HttpStatus.SC_OK) {
throw new RuntimeException("Http response was not SC_OK, but: " + statusCode);
}
} catch(Exception ex){
throw new RuntimeException("Unable to delete file '"
+ fileLocationUrl.toString() + "' from aws S3.", ex);
}
}
}