You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
sdi-service/src/main/java/org/gcube/spatial/data/sdi/engine/impl/TemporaryPersistenceImpl.java

179 lines
5.0 KiB
Java

package org.gcube.spatial.data.sdi.engine.impl;
import java.io.File;
import java.io.FileFilter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Singleton;
import org.apache.commons.io.IOUtils;
import org.gcube.spatial.data.sdi.LocalConfiguration;
import org.gcube.spatial.data.sdi.engine.TemporaryPersistence;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Singleton
public class TemporaryPersistenceImpl implements TemporaryPersistence {
private final static String UPLOADING_FILE_SUFFIX=".part";
private final static FileFilter TO_CHECK_FILES_FILTER=new FileFilter() {
@Override
public boolean accept(File pathname) {
return !pathname.isDirectory()&&!pathname.getName().endsWith(UPLOADING_FILE_SUFFIX);
}
};
// *************** CHECKER THREAD
@AllArgsConstructor
private static class CleanUpThread implements Runnable{
private Long TTL;
private File persistenceLocation;
private FileFilter toCheckFiles;
@Override
public void run() {
try{
log.debug("Executing cleanup..");
long count=0l;
for(File found:persistenceLocation.listFiles(toCheckFiles))
if(found.lastModified()-System.currentTimeMillis()>=TTL){
try{
Files.delete(found.toPath());
}catch(Throwable t){
log.warn("Unable to delete {} ",found.getAbsolutePath(),t);
}
}
log.debug("Cleaned up {} files.",count);
}catch(Throwable t){
log.error("Unexpected error.",t);
}
}
}
// private static TemporaryPersistenceImpl singleton=null;
// *************** INSTANCE LOGIC
private File persistenceLocation=null;
private ScheduledExecutorService service=null;
@Override
@PostConstruct
public void init() {
try {
persistenceLocation=Files.createTempDirectory("SDI").toFile();
System.out.println("************************************** TEMPORARY PERSISTENCE INIT **************************");
System.out.println("SDI-Service - Temporary persistence location is "+persistenceLocation.getAbsolutePath());
System.out.println("**************************************");
log.trace("Temporary persistence is "+persistenceLocation.getAbsolutePath());
// init check thread
service = new ScheduledThreadPoolExecutor (1);
long TTL=Long.parseLong(LocalConfiguration.get().getProperty(LocalConfiguration.TEMPORARY_PERSISTENCE_TTL, "120000"));
log.debug("Temp TTL is {} ",TTL);
long delay=TTL/4;
service.scheduleWithFixedDelay(new CleanUpThread(TTL, persistenceLocation, TO_CHECK_FILES_FILTER), delay, delay, TimeUnit.MILLISECONDS);
}catch(Throwable t) {
throw new RuntimeException("Unable to init persistence ",t);
}
}
@Override
public File getById(String id) throws FileNotFoundException {
File toReturn=new File(persistenceLocation,id);
if(!toReturn.exists()) throw new FileNotFoundException();
return toReturn;
}
@Override
public String store(InputStream is) throws FileNotFoundException, IOException {
String partUUID=getUUID()+".part";
log.debug("Storing file "+partUUID);
File created=transferStream(is, new File(persistenceLocation,partUUID));
String toReturn=created.getName().substring(0, created.getName().lastIndexOf(".")-1);
created.renameTo(new File(persistenceLocation,toReturn));
log.debug("Completed. Part renamed to "+toReturn);
return toReturn;
}
@Override
@PreDestroy
public void clean(String id){
try{
System.out.println("*************************************** TEMPORARY PERSISTENCE PRE DESTROY ******************************");
Files.delete(Paths.get(persistenceLocation.getAbsolutePath(), id));
}catch(Throwable t) {
throw new RuntimeException("Unable to clean up temporary persistence. ",t);
}
}
@Override
public void shutdown() {
log.debug("Shutting down persistence..");
service.shutdownNow();
log.debug("Clearing persistence folder..");
for(File f:persistenceLocation.listFiles())
try{
if(!f.delete()) f.deleteOnExit();
}catch(Throwable t){
log.warn("Exception while clearing persistence.. ",t);
}
}
@Override
public void update(String id, InputStream is) throws FileNotFoundException, IOException {
File toUpdate=getById(id);
transferStream(is,toUpdate);
}
private static File transferStream(InputStream in, File destination) throws FileNotFoundException, IOException{
FileOutputStream out=null;
try{
;
out=new FileOutputStream(destination,false);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
return destination;
}finally{
if(out!=null) IOUtils.closeQuietly(out);
}
}
private static String getUUID(){
return UUID.randomUUID().toString().replace(" ", "_");
}
}