Skip to content
Snippets Groups Projects
Commit af171bc8 authored by Fuentes Serna  Juan Mariano (ID SIS)'s avatar Fuentes Serna Juan Mariano (ID SIS)
Browse files

SSDM-6374 : Microservice server merged from SVN

parent d64588a0
No related branches found
No related tags found
No related merge requests found
Showing
with 141 additions and 102 deletions
...@@ -6,6 +6,7 @@ task wrapper(type: Wrapper) { ...@@ -6,6 +6,7 @@ task wrapper(type: Wrapper) {
} }
repositories { repositories {
mavenCentral()
ivy { ivy {
ivyPattern "http://svnsis.ethz.ch/repos/cisd/ivy-repository/trunk/[organisation]/[module]/[revision]/ivy.xml" ivyPattern "http://svnsis.ethz.ch/repos/cisd/ivy-repository/trunk/[organisation]/[module]/[revision]/ivy.xml"
artifactPattern "http://svnsis.ethz.ch/repos/cisd/ivy-repository/trunk/[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" artifactPattern "http://svnsis.ethz.ch/repos/cisd/ivy-repository/trunk/[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]"
...@@ -24,7 +25,7 @@ dependencies { ...@@ -24,7 +25,7 @@ dependencies {
} }
mainClassName = "ch.ethz.sis.microservices.server.startup.Main" mainClassName = "ch.ethz.sis.microservices.download.server.startup.Main"
distZip { distZip {
into(project.name) { into(project.name) {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"port" : 8080, "port" : 8080,
"services" : [ "services" : [
{ {
"className" : "ch.ethz.sis.microservices.server.services.store.FileInfoHandler", "className" : "ch.ethz.sis.microservices.download.server.services.store.FileInfoHandler",
"url" : "/file-information", "url" : "/file-information",
"parameters" : { "parameters" : {
"openbis-url" : "http://localhost:8888/openbis/openbis/rmi-application-server-v3", "openbis-url" : "http://localhost:8888/openbis/openbis/rmi-application-server-v3",
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
} }
}, },
{ {
"className" : "ch.ethz.sis.microservices.server.services.store.DownloadHandler", "className" : "ch.ethz.sis.microservices.download.server.services.store.DownloadHandler",
"url" : "/download", "url" : "/download",
"parameters" : { "parameters" : {
"openbis-url" : "http://localhost:8888/openbis/openbis/rmi-application-server-v3", "openbis-url" : "http://localhost:8888/openbis/openbis/rmi-application-server-v3",
......
{
"port" : 8080,
"services" : [
{
"className" : "ch.ethz.sis.microservices.download.server.services.store.FileInfoHandler",
"url" : "/file-information",
"parameters" : {
"openbis-url" : "http://localhost:8888/openbis/openbis/rmi-application-server-v3",
"datastore-url" : "http://localhost:8889/datastore_server/rmi-data-store-server-v3",
"services-timeout" : "10000",
"allowedExternalDMSCode" : "ADMIN-BS-MBPR28.D.ETHZ.CH-E96954A7",
"allowedContentCopyPath" : "/Users/localadmin/obis_data/"
}
},
{
"className" : "ch.ethz.sis.microservices.download.server.services.store.DownloadHandler",
"url" : "/download",
"parameters" : {
"openbis-url" : "http://localhost:8888/openbis/openbis/rmi-application-server-v3",
"datastore-url" : "http://localhost:8889/datastore_server/rmi-data-store-server-v3",
"services-timeout" : "10000",
"allowedExternalDMSCode" : "ADMIN-BS-MBPR28.D.ETHZ.CH-E96954A7",
"allowedContentCopyPath" : "/Users/localadmin/obis_data/"
}
}
]
}
\ No newline at end of file
...@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME ...@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=http\://svnsis.ethz.ch/repos/cisd/ivy-repository/trunk/gradle/distribution/4.5/gradle-4.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-4.5-bin.zip
File deleted
package ch.ethz.sis.microservices.api.configuration; package ch.ethz.sis.microservices.download.api.configuration;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
......
package ch.ethz.sis.microservices.api.configuration; package ch.ethz.sis.microservices.download.api.configuration;
import java.util.HashMap; import java.util.HashMap;
......
package ch.ethz.sis.microservices.server.json; package ch.ethz.sis.microservices.download.server.json;
import java.io.FileInputStream; import java.io.FileInputStream;
......
package ch.ethz.sis.microservices.server.json.jackson; package ch.ethz.sis.microservices.download.server.json.jackson;
import java.io.FileInputStream; import java.io.FileInputStream;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import ch.ethz.sis.microservices.server.json.JSONObjectMapper; import ch.ethz.sis.microservices.download.server.json.JSONObjectMapper;
public class JacksonObjectMapper implements JSONObjectMapper public class JacksonObjectMapper implements JSONObjectMapper
{ {
......
package ch.ethz.sis.microservices.server.logging; package ch.ethz.sis.microservices.download.server.logging;
public interface LogFactory { public interface LogFactory {
<T> Logger getLogger(Class<T> clazz); <T> Logger getLogger(Class<T> clazz);
......
package ch.ethz.sis.microservices.server.logging; package ch.ethz.sis.microservices.download.server.logging;
public class LogFactoryFactory { public class LogFactoryFactory {
public LogFactory create(String logFactoryClass) throws Exception { public LogFactory create(String logFactoryClass) throws Exception {
......
package ch.ethz.sis.microservices.server.logging; package ch.ethz.sis.microservices.download.server.logging;
public class LogManager { public class LogManager {
private static LogFactory factory; private static LogFactory factory;
......
package ch.ethz.sis.microservices.server.logging; package ch.ethz.sis.microservices.download.server.logging;
public interface Logger { public interface Logger {
......
package ch.ethz.sis.microservices.server.logging.log4j; package ch.ethz.sis.microservices.download.server.logging.log4j;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import ch.ethz.sis.microservices.server.logging.LogFactory; import ch.ethz.sis.microservices.download.server.logging.LogFactory;
import ch.ethz.sis.microservices.server.logging.Logger; import ch.ethz.sis.microservices.download.server.logging.Logger;
public class Log4J2LogFactory implements LogFactory public class Log4J2LogFactory implements LogFactory
{ {
......
package ch.ethz.sis.microservices.server.logging.log4j; package ch.ethz.sis.microservices.download.server.logging.log4j;
import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.spi.AbstractLogger; import org.apache.logging.log4j.spi.AbstractLogger;
import org.apache.logging.log4j.spi.ExtendedLoggerWrapper; import org.apache.logging.log4j.spi.ExtendedLoggerWrapper;
class Log4JLogger extends ExtendedLoggerWrapper implements ch.ethz.sis.microservices.server.logging.Logger class Log4JLogger extends ExtendedLoggerWrapper implements ch.ethz.sis.microservices.download.server.logging.Logger
{ {
private final String FQCN; private final String FQCN;
......
package ch.ethz.sis.microservices.server.services; package ch.ethz.sis.microservices.download.server.services;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import ch.ethz.sis.microservices.api.configuration.ServiceConfig; import ch.ethz.sis.microservices.download.api.configuration.ServiceConfig;
public abstract class Service extends HttpServlet public abstract class Service extends HttpServlet
{ {
......
package ch.ethz.sis.microservices.server.services.store; package ch.ethz.sis.microservices.download.server.services.store;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.Arrays; import java.util.Arrays;
import java.util.Deque;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import ch.ethz.sis.microservices.server.logging.LogManager; import ch.ethz.sis.microservices.download.server.logging.LogManager;
import ch.ethz.sis.microservices.server.logging.Logger; import ch.ethz.sis.microservices.download.server.logging.Logger;
import ch.ethz.sis.microservices.server.services.Service; import ch.ethz.sis.microservices.download.server.services.Service;
import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi; import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi;
import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.search.SearchResult;
import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.ContentCopy; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.ContentCopy;
import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.DataSet;
import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetFetchOptions; import ch.ethz.sis.openbis.generic.asapi.v3.dto.dataset.fetchoptions.DataSetFetchOptions;
...@@ -29,7 +26,6 @@ import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.DataSetFile; ...@@ -29,7 +26,6 @@ import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.DataSetFile;
import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.fetchoptions.DataSetFileFetchOptions; import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.fetchoptions.DataSetFileFetchOptions;
import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.search.DataSetFileSearchCriteria; import ch.ethz.sis.openbis.generic.dssapi.v3.dto.datasetfile.search.DataSetFileSearchCriteria;
import ch.systemsx.cisd.common.spring.HttpInvokerUtils; import ch.systemsx.cisd.common.spring.HttpInvokerUtils;
import lombok.Value;
public abstract class AbstractFileServiceHandler extends Service public abstract class AbstractFileServiceHandler extends Service
{ {
...@@ -70,10 +66,10 @@ public abstract class AbstractFileServiceHandler extends Service ...@@ -70,10 +66,10 @@ public abstract class AbstractFileServiceHandler extends Service
Path pathToFile = getPathToFile(contentCopyPath, datasetPathToFile); Path pathToFile = getPathToFile(contentCopyPath, datasetPathToFile);
if (isFileAccessible) if (isFileAccessible)
{ {
success(pathToFile, response); success(pathToFile, request, response);
} else } else
{ {
failure(pathToFile, response); failure(pathToFile, request, response);
} }
} }
...@@ -85,9 +81,9 @@ public abstract class AbstractFileServiceHandler extends Service ...@@ -85,9 +81,9 @@ public abstract class AbstractFileServiceHandler extends Service
doAction(request, response); doAction(request, response);
} }
protected abstract void success(Path pathToFile, HttpServletResponse response) throws ServletException, IOException; protected abstract void success(Path pathToFile, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
protected abstract void failure(Path pathToFile, HttpServletResponse response) throws ServletException, IOException; protected abstract void failure(Path pathToFile, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;
private DataSet getDataset(String openbisURL, int openbisTimeout, String sessionToken, String datasetPermId, String externalDMSCode, private DataSet getDataset(String openbisURL, int openbisTimeout, String sessionToken, String datasetPermId, String externalDMSCode,
String contentCopyPath) String contentCopyPath)
...@@ -110,68 +106,17 @@ public abstract class AbstractFileServiceHandler extends Service ...@@ -110,68 +106,17 @@ public abstract class AbstractFileServiceHandler extends Service
} }
return null; return null;
} }
/*
* Less recently used cache
* Keeps maxSize items
*/
@Value
private static class LRUCache<KEY, VALUE> {
int maxSize;
Map<KEY, VALUE> cacheByKey = new ConcurrentHashMap<>();
Deque<KEY> cachePriority = new ConcurrentLinkedDeque<>();
public LRUCache(int maxSize) {
this.maxSize = maxSize;
}
public void add(KEY key, VALUE value) {
// Remove if existing
if(cacheByKey.containsKey(key)) {
cacheByKey.remove(key);
cachePriority.remove(key);
}
// Add again
cacheByKey.put(key, value);
cachePriority.addFirst(key);
// Remove oldest if the list grow too much
if(cachePriority.size() > maxSize) {
cacheByKey.remove(cachePriority.removeLast());
}
}
public VALUE get(KEY key) {
// Refresh Prio
if(cacheByKey.containsKey(key)) {
cachePriority.remove(key);
cachePriority.addFirst(key);
}
return cacheByKey.get(key);
}
}
private static LRUCache<String, List<DataSetFile>> cache = new LRUCache<>(1000);
private DataSetFile getDatasetFile(String datastoreURL, int datastoreTimeout, String sessionToken, String datasetPermId, private DataSetFile getDatasetFile(String datastoreURL, int datastoreTimeout, String sessionToken, String datasetPermId,
String datasetPathToFile) String datasetPathToFile)
{ {
List<DataSetFile> files = cache.get(datasetPermId); IDataStoreServerApi v3Dss = HttpInvokerUtils.createServiceStub(IDataStoreServerApi.class, datastoreURL, datastoreTimeout);
if(files == null) { DataSetFileSearchCriteria searchCriteria = new DataSetFileSearchCriteria();
IDataStoreServerApi v3Dss = HttpInvokerUtils.createServiceStub(IDataStoreServerApi.class, datastoreURL, datastoreTimeout); searchCriteria.withDataSet().withCode().thatEquals(datasetPermId);
DataSetFileSearchCriteria searchCriteria = new DataSetFileSearchCriteria(); DataSetFileFetchOptions fetchOptions = new DataSetFileFetchOptions();
searchCriteria.withDataSet().withCode().thatEquals(datasetPermId); SearchResult<DataSetFile> files = v3Dss.searchFiles(sessionToken, searchCriteria, fetchOptions);
DataSetFileFetchOptions fetchOptions = new DataSetFileFetchOptions(); for (DataSetFile file : files.getObjects())
files = v3Dss.searchFiles(sessionToken, searchCriteria, fetchOptions).getObjects();
cache.add(datasetPermId, files);
}
for (DataSetFile file : files)
{ {
if (file.getPath().equals(datasetPathToFile)) if (file.getPath().equals(datasetPathToFile))
{ {
......
package ch.ethz.sis.microservices.server.services.store; package ch.ethz.sis.microservices.download.server.services.store;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import ch.ethz.sis.microservices.server.logging.LogManager; import ch.ethz.sis.microservices.download.server.logging.LogManager;
import ch.ethz.sis.microservices.server.logging.log4j.Log4J2LogFactory; import ch.ethz.sis.microservices.download.server.logging.log4j.Log4J2LogFactory;
import ch.ethz.sis.microservices.util.HttpClient; import ch.ethz.sis.microservices.download.server.startup.HttpClient;
import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi; import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi;
import ch.systemsx.cisd.common.spring.HttpInvokerUtils; import ch.systemsx.cisd.common.spring.HttpInvokerUtils;
...@@ -17,13 +17,13 @@ public class AbstractFileServiceTest ...@@ -17,13 +17,13 @@ public class AbstractFileServiceTest
LogManager.setLogFactory(new Log4J2LogFactory()); LogManager.setLogFactory(new Log4J2LogFactory());
} }
public static void test(String openbisURL, String serviceURL, String user, String pass) throws Exception public static void test(String openbisURL, String serviceURL, String user, String pass, Long offset) throws Exception
{ {
// Service // Service
String externalDMSCode = "ADMIN-BS-MBPR28.D.ETHZ.CH-E96954A7"; String externalDMSCode = "ADMIN-BS-MBPR28.D.ETHZ.CH-E96954A7";
String contentCopyPath = "/Users/localadmin/obis_data/data"; String contentCopyPath = "/Users/localadmin/obis_data/data1";
String datasetPermId = "20180131090547942-3"; String datasetPermId = "20180523115921026-50";
String datasetPathToFile = "file"; String datasetPathToFile = "openBIS-installation-standard-technologies-SNAPSHOT-r1526484921.tar.gz";
// Obtain session token from openBIS // Obtain session token from openBIS
int timeout = 10000; int timeout = 10000;
...@@ -36,11 +36,15 @@ public class AbstractFileServiceTest ...@@ -36,11 +36,15 @@ public class AbstractFileServiceTest
parameters.put("externalDMSCode", externalDMSCode); parameters.put("externalDMSCode", externalDMSCode);
parameters.put("contentCopyPath", contentCopyPath); parameters.put("contentCopyPath", contentCopyPath);
parameters.put("datasetPathToFile", datasetPathToFile); parameters.put("datasetPathToFile", datasetPathToFile);
if(offset != null) {
parameters.put("offset", offset.toString());
}
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
byte[] response = HttpClient.doGet(serviceURL, parameters); byte[] response = HttpClient.doGet(serviceURL, parameters);
long end = System.currentTimeMillis(); long end = System.currentTimeMillis();
System.out.println(new String(response)); System.out.println("Response Size: " + response.length);
System.out.println("Time: " + (end - start)); System.out.println("Time: " + (end - start));
} }
} }
package ch.ethz.sis.microservices.server.services.store; package ch.ethz.sis.microservices.download.server.services.store;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import ch.ethz.sis.microservices.server.logging.LogManager; import ch.ethz.sis.microservices.download.server.logging.LogManager;
import ch.ethz.sis.microservices.server.logging.Logger; import ch.ethz.sis.microservices.download.server.logging.Logger;
public class DownloadHandler extends AbstractFileServiceHandler public class DownloadHandler extends AbstractFileServiceHandler
{ {
private static Logger logger = LogManager.getLogger(DownloadHandler.class); private static Logger logger = LogManager.getLogger(DownloadHandler.class);
@Override @Override
protected void success(Path pathToFile, HttpServletResponse response) throws ServletException, IOException protected void success(Path pathToFile, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{ {
// Request parameters
String offsetP = request.getParameter("offset");
long offset = 0;
if(offsetP != null) {
offset = Long.parseLong(offsetP);
}
long size = Files.size(pathToFile) - offset;
if(size < 0) {
throw new IllegalArgumentException("offset to read starts beyond end of file");
}
// Response
response.setContentType("application/octet-stream"); response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=" + pathToFile.getFileName().toString()); response.setHeader("Content-Disposition", "attachment; filename=" + pathToFile.getFileName().toString());
response.setHeader("Content-Length", Long.toString(Files.size(pathToFile))); response.setHeader("Content-Length", Long.toString(Files.size(pathToFile)));
Files.copy(pathToFile, response.getOutputStream());
InputStream is = Files.newInputStream(pathToFile);
is.skip(offset);
copy(is, response.getOutputStream(), size);
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
} }
private static final int BUFFER_SIZE = 1024;
private static void copy(InputStream source, OutputStream destination, long sourceSize) throws IOException {
byte[] buf = new byte[BUFFER_SIZE];
int readed;
while ((readed = source.read(buf)) > 0) {
destination.write(buf, 0, readed);
}
}
@Override @Override
protected void failure(Path pathToFile, HttpServletResponse response) throws ServletException, IOException protected void failure(Path pathToFile, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{ {
response.setStatus(HttpServletResponse.SC_NOT_FOUND); response.setStatus(HttpServletResponse.SC_NOT_FOUND);
} }
......
package ch.ethz.sis.microservices.server.services.store; package ch.ethz.sis.microservices.download.server.services.store;
public class DownloadHandlerTest public class DownloadHandlerTest
{ {
...@@ -9,6 +9,7 @@ public class DownloadHandlerTest ...@@ -9,6 +9,7 @@ public class DownloadHandlerTest
"http://localhost:8888/openbis/openbis/rmi-application-server-v3", "http://localhost:8888/openbis/openbis/rmi-application-server-v3",
"http://localhost:8080/download", "http://localhost:8080/download",
"admin", "admin",
"admin"); "admin",
null);
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment