diff --git a/.classpath b/.classpath
index e43402f..63c80a6 100644
--- a/.classpath
+++ b/.classpath
@@ -15,11 +15,13 @@
+
+
@@ -30,6 +32,7 @@
+
diff --git a/.project b/.project
index 446545d..4bd607c 100644
--- a/.project
+++ b/.project
@@ -5,11 +5,21 @@
+
+ org.eclipse.wst.common.project.facet.core.builder
+
+
+
org.eclipse.jdt.core.javabuilder
+
+ org.eclipse.wst.validation.validationbuilder
+
+
+
org.eclipse.m2e.core.maven2Builder
@@ -17,7 +27,11 @@
+ org.eclipse.jem.workbench.JavaEMFNature
+ org.eclipse.wst.common.modulecore.ModuleCoreNature
org.eclipse.jdt.core.javanature
org.eclipse.m2e.core.maven2Nature
+ org.eclipse.wst.common.project.facet.core.nature
+ org.eclipse.wst.jsdt.core.jsNature
diff --git a/distro/changelog.xml b/distro/changelog.xml
index cfc9a9c..fd19851 100644
--- a/distro/changelog.xml
+++ b/distro/changelog.xml
@@ -1,5 +1,8 @@
-
+
+ integration with storageHub
+
+
add user script is executed also when configfile.csv is not present
diff --git a/distro/web.xml b/distro/web.xml
index e7c1bee..ef29b85 100644
--- a/distro/web.xml
+++ b/distro/web.xml
@@ -11,6 +11,10 @@
addUserScript
/usr/local/bin/rusersadd
+
+ unmountScript
+ /usr/local/bin/rconnector_unmount
+
storedKeyPath
/var/lib/rstudio-server/secure-cookie-key
diff --git a/pom.xml b/pom.xml
index 612d26e..b765d74 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,9 +1,10 @@
-
4.0.0
org.gcube.data.analysis
r-connector
- 2.1.3-SNAPSHOT
+ 2.1.4-SNAPSHOT
RConnector
makes R available in the infrastructure
@@ -64,7 +65,12 @@
tabulardata-client-library
[2.0.0-SNAPSHOT, 3.0.0-SNAPSHOT)
-
+
+ org.gcube.data-access
+ sh-fuse-integration
+ 1.0.0-SNAPSHOT
+
+
javax.ws.rs
diff --git a/src/main/java/org/gcube/data/analysis/rconnector/ConfigFileWriter.java b/src/main/java/org/gcube/data/analysis/rconnector/ConfigFileWriter.java
index 4d7bae1..9c6660f 100644
--- a/src/main/java/org/gcube/data/analysis/rconnector/ConfigFileWriter.java
+++ b/src/main/java/org/gcube/data/analysis/rconnector/ConfigFileWriter.java
@@ -1,13 +1,13 @@
package org.gcube.data.analysis.rconnector;
-import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStreamReader;
import javax.inject.Singleton;
+import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
+import org.gcube.common.scope.api.ScopeProvider;
+
import lombok.extern.slf4j.Slf4j;
@@ -21,38 +21,10 @@ public class ConfigFileWriter {
usersHome=usersHome+"/";
File userDir = new File(usersHome+login);
File configFile= new File(userDir, fileName);
- executeCommandLine(scriptToExecute,login);
+ Utils.executeCommandLine(scriptToExecute,login, SecurityTokenProvider.instance.get(), ScopeProvider.instance.get());
return writeFile(info, configFile);
}
- private String executeCommandLine(String cmd, String login){
- log.debug("executing command "+cmd+" "+login);
- Process process = null;
- String lastline = "";
- try {
-
- ProcessBuilder pb = new ProcessBuilder(cmd, login);
- process = pb.start();
-
- try {
- process.waitFor();
- } catch (InterruptedException e) {
- log.warn("interrupt Exception on process",e);
- }
-
- BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()));
- String line = br.readLine();
- while (line!=null){
- lastline += line;
- line = br.readLine();
- }
- } catch (IOException e) {
- log.error("error executing command line",e);
- }
- log.debug("command result line is "+lastline);
- return lastline;
- }
-
private boolean writeFile(Info info, File pathToFile){
log.debug("writing config file");
StringBuffer sb = new StringBuffer();
diff --git a/src/main/java/org/gcube/data/analysis/rconnector/DisconnectResource.java b/src/main/java/org/gcube/data/analysis/rconnector/DisconnectResource.java
index 86b11e9..3d7791b 100644
--- a/src/main/java/org/gcube/data/analysis/rconnector/DisconnectResource.java
+++ b/src/main/java/org/gcube/data/analysis/rconnector/DisconnectResource.java
@@ -1,5 +1,6 @@
package org.gcube.data.analysis.rconnector;
+import javax.inject.Inject;
import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
@@ -10,21 +11,39 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import org.gcube.common.authorization.library.provider.AuthorizationProvider;
+
import lombok.extern.slf4j.Slf4j;
@Path("disconnect")
@Slf4j
public class DisconnectResource {
+
@Context ServletContext context;
+ @Inject
+ InfoRetriever infoRetriever;
+
@GET
@Produces(MediaType.TEXT_HTML)
public Response disconnect(@Context HttpServletRequest req) {
log.info("disconnect called ");
String rStudioServerAddress = context==null?"":context.getInitParameter("rStudioAddress");
- log.info(rStudioServerAddress);
+ String scriptToExecute = context.getInitParameter("unmountScript");
+
+ String login = null;
+ for (Cookie cookie : req.getCookies())
+ if (cookie.getName().equals("user-id"))
+ login = cookie.getValue();
+
+ if (login==null)
+ return Response.serverError().build();
+
try{
+
+ Utils.executeCommandLine(scriptToExecute, login);
+
boolean found = false;
for (Cookie cookie : req.getCookies())
if (cookie.getName().equals("user-id")){
@@ -39,8 +58,8 @@ public class DisconnectResource {
).build();
else return Response.ok(context.getClassLoader().getResourceAsStream("inactivesession.html")).build();
}catch(Exception e){
- e.printStackTrace();
- return null;
+ log.error("erorr disconnecting from Rstudio",e);
+ return Response.serverError().build();
}
}
diff --git a/src/main/java/org/gcube/data/analysis/rconnector/InfoRetriever.java b/src/main/java/org/gcube/data/analysis/rconnector/InfoRetriever.java
index d5a610e..00033c1 100644
--- a/src/main/java/org/gcube/data/analysis/rconnector/InfoRetriever.java
+++ b/src/main/java/org/gcube/data/analysis/rconnector/InfoRetriever.java
@@ -10,8 +10,6 @@ import java.util.regex.Pattern;
import javax.inject.Inject;
import javax.inject.Singleton;
-import lombok.extern.slf4j.Slf4j;
-
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.database.DatabaseEndpointIdentifier;
import org.gcube.common.database.DatabaseProvider;
@@ -25,6 +23,8 @@ import org.gcube.data.analysis.tabulardata.model.metadata.common.NamesMetadata;
import org.gcube.data.analysis.tabulardata.model.metadata.table.DatasetViewTableMetadata;
import org.gcube.data.analysis.tabulardata.model.table.Table;
+import lombok.extern.slf4j.Slf4j;
+
@Slf4j
@Singleton
public class InfoRetriever {
@@ -32,7 +32,6 @@ public class InfoRetriever {
@Inject
DatabaseProvider databaseProvider;
-
@SuppressWarnings("unchecked")
public Info retrieve(String userName, Long tabularResourceId){
try {
diff --git a/src/main/java/org/gcube/data/analysis/rconnector/Resource.java b/src/main/java/org/gcube/data/analysis/rconnector/Resource.java
index 057ea1a..b4e7301 100644
--- a/src/main/java/org/gcube/data/analysis/rconnector/Resource.java
+++ b/src/main/java/org/gcube/data/analysis/rconnector/Resource.java
@@ -1,9 +1,11 @@
package org.gcube.data.analysis.rconnector;
import java.io.File;
+import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.file.Files;
+import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
@@ -20,11 +22,12 @@ import javax.ws.rs.core.NewCookie;
import javax.ws.rs.core.Response;
import javax.xml.bind.DatatypeConverter;
-import lombok.extern.slf4j.Slf4j;
-
import org.gcube.common.authorization.library.provider.AuthorizationProvider;
import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
import org.gcube.common.scope.api.ScopeProvider;
+import org.gcube.data.access.storagehub.fs.StorageHubFS;
+
+import lombok.extern.slf4j.Slf4j;
@Path("connect/")
@Slf4j
@@ -35,85 +38,89 @@ public class Resource {
@Inject
InfoRetriever infoRetriever;
-
+
@Context ServletContext context;
-
-
+
+
@Path("/{trId}")
@GET
public Response connect(@PathParam("trId") Long tabularResourceId) {
log.info("connect called with user {} and trID {} in scope {}",AuthorizationProvider.instance.get().getClient().getId(), tabularResourceId, ScopeProvider.instance.get());
+
+ String login = AuthorizationProvider.instance.get().getClient().getId();
String usersHome = context.getInitParameter("usersHome");
String filename = context.getInitParameter("filename");
String scriptToExecute = context.getInitParameter("addUserScript");
- if (ScopeProvider.instance.get()==null || AuthorizationProvider.instance.get().getClient().getId() == null || tabularResourceId ==null ) return Response.serverError().build();
+ if (ScopeProvider.instance.get()==null || login == null || tabularResourceId ==null ) return Response.serverError().build();
Info info;
try{
- info = infoRetriever.retrieve(AuthorizationProvider.instance.get().getClient().getId(), tabularResourceId);
+ info = infoRetriever.retrieve(login, tabularResourceId);
log.debug("retrieved info: "+info);
}catch(Exception e){
log.error("error connecting to r",e);
return Response.serverError().build();
}
- if (!writer.write(info, AuthorizationProvider.instance.get().getClient().getId(), usersHome, filename, scriptToExecute)) return Response.serverError().build();
-
- return createResponse(AuthorizationProvider.instance.get().getClient().getId());
+ if (!writer.write(info, login, usersHome, filename, scriptToExecute)) return Response.serverError().build();
+
+ return createResponse(login);
}
-
+
@GET
public Response connect() {
log.info("connect called with user {} in scope {}",AuthorizationProvider.instance.get().getClient().getId(), ScopeProvider.instance.get());
+ String login = AuthorizationProvider.instance.get().getClient().getId();
String usersHome = context.getInitParameter("usersHome");
String filename = context.getInitParameter("filename");
String scriptToExecute = context.getInitParameter("addUserScript");
- if (AuthorizationProvider.instance.get().getClient().getId() == null ) return Response.serverError().build();
+ if (login == null ) return Response.serverError().build();
Info info = new Info();
- info.setUsername(AuthorizationProvider.instance.get().getClient().getId());
+ info.setUsername(login);
info.setToken(SecurityTokenProvider.instance.get());
- if (!writer.write(info, AuthorizationProvider.instance.get().getClient().getId(), usersHome, filename, scriptToExecute)) return Response.serverError().build();
+ if (!writer.write(info, login, usersHome, filename, scriptToExecute)) return Response.serverError().build();
+
return createResponse(AuthorizationProvider.instance.get().getClient().getId());
}
-
+
private Response createResponse(String userName){
try{
String keyFilePath = context.getInitParameter("storedKeyPath");
String rStudioServerAddress = context.getInitParameter("rStudioAddress");
-
+
log.debug("key file path: "+keyFilePath);
log.debug("rstudio server address: "+rStudioServerAddress);
-
+
Calendar now = Calendar.getInstance();
now.add(Calendar.YEAR, 10);
now.add(Calendar.DAY_OF_YEAR, -1);
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH);
String format = sdf.format(now.getTime());
-
+
File keyFile = new File(keyFilePath);
if (!keyFile.exists())
return Response.serverError().build();
-
+
byte[] keyByte = Files.readAllBytes(keyFile.toPath());
-
+
SecretKeySpec keySpec = new SecretKeySpec(keyByte,
- "HmacSHA256");
+ "HmacSHA256");
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(keySpec);
byte[] result = mac.doFinal((userName+format).getBytes());
String encoded = URLEncoder.encode(DatatypeConverter.printBase64Binary(result));
-
+
String cookieValue = userName+"|"+URLEncoder.encode(format).replaceAll("\\+", "%20")+"|"+encoded;
NewCookie cookie = new NewCookie("user-id",
cookieValue,
"/", rStudioServerAddress, "", -1, false, true );
-
-
+
+
return Response.seeOther(new URI("http://"+rStudioServerAddress))
.cookie(cookie).build();
}catch(Exception e){
log.error("error creating response", e);
return Response.serverError().build();}
}
-
+
}
diff --git a/src/main/java/org/gcube/data/analysis/rconnector/Utils.java b/src/main/java/org/gcube/data/analysis/rconnector/Utils.java
new file mode 100644
index 0000000..c18a86e
--- /dev/null
+++ b/src/main/java/org/gcube/data/analysis/rconnector/Utils.java
@@ -0,0 +1,43 @@
+package org.gcube.data.analysis.rconnector;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Utils {
+
+ private static Logger log = LoggerFactory.getLogger(Utils.class);
+
+ protected static String executeCommandLine(String ... args){
+ log.debug("executing command {}",Arrays.asList(args));
+ Process process = null;
+ String lastline = "";
+ try {
+
+ ProcessBuilder pb = new ProcessBuilder(args);
+ process = pb.start();
+
+ try {
+ process.waitFor();
+ } catch (InterruptedException e) {
+ log.warn("interrupt Exception on process",e);
+ }
+
+ BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()));
+ String line = br.readLine();
+ while (line!=null){
+ lastline += line;
+ line = br.readLine();
+ }
+ } catch (IOException e) {
+ log.error("error executing command line",e);
+ }
+ log.debug("command result line is {} ",lastline);
+ return lastline;
+ }
+
+}
diff --git a/src/main/resources/META-INF/beans.xml b/src/main/resources/META-INF/beans.xml
index 7c7e8db..e10a85a 100644
--- a/src/main/resources/META-INF/beans.xml
+++ b/src/main/resources/META-INF/beans.xml
@@ -1,5 +1,3 @@
-
+
+
\ No newline at end of file