diff --git a/.classpath b/.classpath
index 2c48a08..8c7e737 100644
--- a/.classpath
+++ b/.classpath
@@ -1,18 +1,18 @@
-
+
-
+
-
+
@@ -30,16 +30,16 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/.settings/com.gwtplugins.gdt.eclipse.core.prefs b/.settings/com.gwtplugins.gdt.eclipse.core.prefs
index a33d7f8..f521e97 100644
--- a/.settings/com.gwtplugins.gdt.eclipse.core.prefs
+++ b/.settings/com.gwtplugins.gdt.eclipse.core.prefs
@@ -1,4 +1,4 @@
eclipse.preferences.version=1
-lastWarOutDir=/Users/massi/Documents/workspace/rstudio-wrapper-portlet/target/rstudio-wrapper-portlet-1.3.1-SNAPSHOT
+lastWarOutDir=${webappDirectory}
warSrcDir=src/main/webapp
warSrcDirIsOutput=false
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index 8db228c..4e4a3ad 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -1,9 +1,9 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
-org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.release=disabled
-org.eclipse.jdt.core.compiler.source=1.7
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml
index c5b2895..0e7b425 100644
--- a/.settings/org.eclipse.wst.common.project.facet.core.xml
+++ b/.settings/org.eclipse.wst.common.project.facet.core.xml
@@ -1,10 +1,10 @@
-
+
diff --git a/pom.xml b/pom.xml
index 4e9d5fb..de48eb9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -24,10 +24,10 @@
distro
6.2.5
6.2.10.12
- /Users/massi/portal/liferay-portal-6.2-ce-ga6/deploy
- /Users/massi/portal/liferay-portal-6.2-ce-ga6/tomcat-7.0.62/webapps
- /Users/massi/portal/liferay-portal-6.2-ce-ga6/tomcat-7.0.62/lib/ext
- /Users/massi/portal/liferay-portal-6.2-ce-ga6/tomcat-7.0.62/webapps/ROOT
+ ${system.CATALINA_HOME}/../deploy
+ ${system.CATALINA_HOME}/webapps
+ ${system.CATALINA_HOME}/lib/ext
+ ${system.CATALINA_HOME}/webapps/ROOT
diff --git a/src/main/java/org/gcube/portlets/user/rstudio_wrapper_portlet/server/RStudioServiceImpl.java b/src/main/java/org/gcube/portlets/user/rstudio_wrapper_portlet/server/RStudioServiceImpl.java
index 21ccb33..6fa20bc 100644
--- a/src/main/java/org/gcube/portlets/user/rstudio_wrapper_portlet/server/RStudioServiceImpl.java
+++ b/src/main/java/org/gcube/portlets/user/rstudio_wrapper_portlet/server/RStudioServiceImpl.java
@@ -5,12 +5,17 @@ import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
import java.net.MalformedURLException;
+import java.net.URI;
+import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.gcube.common.portal.PortalContext;
+import org.gcube.common.resources.gcore.GCoreEndpoint;
+import org.gcube.common.resources.gcore.GCoreEndpoint.Profile.Endpoint;
import org.gcube.common.resources.gcore.ServiceEndpoint;
+import org.gcube.common.resources.gcore.utils.Group;
import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.portlets.user.rstudio_wrapper_portlet.client.RStudioService;
import org.gcube.portlets.user.rstudio_wrapper_portlet.shared.RStudioInstance;
@@ -37,6 +42,9 @@ public class RStudioServiceImpl extends RemoteServiceServlet implements RStudioS
private static final String RSTUDIO_INSTANCES = "RStudio-Instances";
private static final String RSTUDIO_URL = "RStudio-URL";
private static final String RCONNECTOR_EntryName = "org.gcube.data.analysis.rconnector.RConnector";
+ private static final String GCORE_SERVICE_NAME = "RConnector";
+ private static final String GCORE_SERVICE_CLASS = "DataAnalysis";
+
private static final String PATH_TO_RCONNECTOR = "/r-connector/gcube/service/connect";
private static final String SERVICE_EP_NAME = "RConnector";
@@ -75,13 +83,13 @@ public class RStudioServiceImpl extends RemoteServiceServlet implements RStudioS
_log.debug("calling rConnector with scope = " + scope + " and token = "+token );
List resources = getRStudioServiceEndpoints(scope);
if (resources.size() == 0){
- _log.warn("There is no Service Endpoint having CATEGORY " + CATEGORY +" and NAME " + SERVICE_EP_NAME + " in this scope. Returning default instance");
- toReturn = rConnector().build().connect().toURL().toExternalForm();
+ _log.info("There is no Service Endpoint having CATEGORY " + CATEGORY +" and NAME " + SERVICE_EP_NAME + " in this scope. Passing to the gCore instances");
+ toReturn = getRStudioGCoreEndpoint(pContext, userId, curUser, scope, token);
} else {
UserManager um = new LiferayUserManager();
_log.debug("Checking if user " + curUser.getFullname() + " has already an RStudio Instance set ... ");
String hostedOnSet = null;
-
+
//check if an RStudio instance was previously set (RETRO-COMPATIBILY)
if (um.readCustomAttr(userId, RSTUDIO_URL) != null && um.readCustomAttr(userId, RSTUDIO_URL).toString().compareTo("") != 0) {
_log.debug("User had already an RStudio Instance set, upgrading to new version ");
@@ -89,9 +97,9 @@ public class RStudioServiceImpl extends RemoteServiceServlet implements RStudioS
writeRStudioInstanceInScope(um, curUser, scope, hostedOnSet);
um.saveCustomAttr(userId, RSTUDIO_URL, ""); //reset the old value to blank so that from now on it will read from the new field
}
-
+
hostedOnSet = getUserRStudioInstances(um,curUser).get(scope);
-
+
_log.info("**** Checking if still exist on this scope: " + scope);
//if the instance exists and is still available in the given context
if (hostedOnSet != null && checkRStudioInstanceExistence(curUser, hostedOnSet, resources) ) {
@@ -147,11 +155,105 @@ public class RStudioServiceImpl extends RemoteServiceServlet implements RStudioS
_log.info("returning URL from rConnector = "+toReturn);
if (!toReturn.startsWith("https")) {
toReturn = toReturn.replace("http:", "https:");
+ toReturn = toReturn.replace(":8080", "");
+ toReturn = toReturn.replace(":80", "");
_log.info("Changed URL from rConnector to support SSL: "+toReturn);
}
return toReturn;
}
+
+ /**
+ * new method
+ * @param pContext
+ * @param userId
+ * @param curUser
+ * @param scope
+ * @param token
+ * @return
+ */
+ private String getRStudioGCoreEndpoint(PortalContext pContext, long userId, GCubeUser curUser, String scope, String token) {
+ String toReturn = "";
+ UserManager um = new LiferayUserManager();
+ _log.debug("Checking if user " + curUser.getFullname() + " has already an RStudio Instance set ... ");
+ String hostedOnSet = null;
+ try {
+ //check if an RStudio instance was previously set (RETRO-COMPATIBILY)
+ if (um.readCustomAttr(userId, RSTUDIO_URL) != null && um.readCustomAttr(userId, RSTUDIO_URL).toString().compareTo("") != 0) {
+ _log.debug("User had already an RStudio Instance set, upgrading to new version ");
+ hostedOnSet = (String) um.readCustomAttr(userId, RSTUDIO_URL);
+ writeRStudioInstanceInScope(um, curUser, scope, hostedOnSet);
+ um.saveCustomAttr(userId, RSTUDIO_URL, ""); //reset the old value to blank so that from now on it will read from the new field
+ }
+ hostedOnSet = getUserRStudioInstances(um,curUser).get(scope);
+ _log.info("**** Checking if the user instance " + hostedOnSet+" exists in the VO for this VRE: " + scope);
+ //if the instance exists and is still available in the given context
+ List gCoreResources = getRStudioGCoreEndpoints(scope);
+ if (hostedOnSet != null && checkRStudioGCoreInstanceExistence(curUser, hostedOnSet, gCoreResources) ) {
+ toReturn = getRConnectorURL(hostedOnSet, token);
+ _log.info("User " + curUser.getFullname() + " has RStudio Instance set and is valid, returning rConnector URL " + toReturn);
+ }
+ else {//need to find the RStudio
+ _log.info("User " + curUser.getFullname() + " DOES NOT have RStudio Instance set or the instance previous set no longer exists, calculating allocation ... ");
+ HashMap rStudioDistributionMap = new HashMap<>();
+ for (GCoreEndpoint res : gCoreResources) {
+ String hostedOn = extractGCoreEndpointHostAndPort(res);
+ rStudioDistributionMap.put(hostedOn, 0);
+ }
+ List vreUsers = um.listUsersByGroup(pContext.getCurrentGroupId(getThreadLocalRequest()), false);
+ _log.debug("VRE " + scope + " has totalUsers = " + vreUsers.size());
+ for (GCubeUser gCubeUser : vreUsers) {
+ if (getUserRStudioInstances(um,gCubeUser).get(scope) != null) {
+ String hostedOn = getUserRStudioInstances(um,gCubeUser).get(scope);
+ if (rStudioDistributionMap.containsKey(hostedOn)) {
+ int noToSet = rStudioDistributionMap.get(hostedOn)+1;
+ rStudioDistributionMap.put(hostedOn, noToSet);
+ }
+ }
+ }
+ _log.info("VRE - RStudio allocaiton map as follows: ");
+ int min = 0;
+ int i = 0;
+ String host2Select = "";
+ for (String host : rStudioDistributionMap.keySet()) {
+ _log.info("Host " + host + " has # users=" + rStudioDistributionMap.get(host));
+ if (i==0) {
+ host2Select = host;
+ min = rStudioDistributionMap.get(host);
+ } else {
+ int usersNo = rStudioDistributionMap.get(host);
+ if (usersNo < min) {
+ _log.info("Host " + host + " has LESS users than " + host2Select + " updating");
+ host2Select = host;
+ }
+ }
+ i++;
+ }
+ writeRStudioInstanceInScope(um, curUser, scope, host2Select);
+ _log.debug("User " + curUser.getFullname() + " RStudio gCore Instance set calculated = " + host2Select + " for context " + scope);
+ toReturn = getRConnectorURL(host2Select, token);
+ _log.debug("User " + curUser.getFullname() + " has RStudio gCore Instance set, returning rConnector URL " + toReturn);
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return toReturn;
+ }
+
+ private List getRStudioGCoreEndpoints(String scope) {
+ _log.debug("getRStudioGCoreEndpoints on scope="+scope );
+ String currScope = ScopeProvider.instance.get();
+ ScopeProvider.instance.set(scope);
+ SimpleQuery query = queryFor(GCoreEndpoint.class);
+ query.addCondition("$resource/Profile/ServiceName/text() eq '"+ GCORE_SERVICE_NAME +"'");
+ query.addCondition("$resource/Profile/ServiceClass/text() eq '"+ GCORE_SERVICE_CLASS +"'");
+ DiscoveryClient client = clientFor(GCoreEndpoint.class);
+ List toReturn = client.submit(query);
+ ScopeProvider.instance.set(currScope);
+ return toReturn;
+ }
+
/**
*
* @param um
@@ -204,11 +306,15 @@ public class RStudioServiceImpl extends RemoteServiceServlet implements RStudioS
_log.warn("Could not find an integer after :, using default port 80");
}
//http://rstudio-dev.d4science.org:80/r-connector/gcube/service/connect?gcube-token=6fa92d94-6568-4510-8443-a1c5ecdf1c7d-98187548s
- if (port == 443 || port == 8443)
- return "https://"+hostedOn+PATH_TO_RCONNECTOR+"?gcube-token="+token;
+ String toReturn = "";
+ if (port == 443 || port == 8443) {
+ toReturn = "https://"+hostedOn+PATH_TO_RCONNECTOR+"?gcube-token="+token;
+ }
else {
- return "http://"+hostedOn+PATH_TO_RCONNECTOR+"?gcube-token="+token;
+ toReturn = "http://"+hostedOn+PATH_TO_RCONNECTOR+"?gcube-token="+token;
}
+ _log.debug("**getRConnectorURL toReturn="+toReturn);
+ return toReturn;
}
/**
*
@@ -227,13 +333,32 @@ public class RStudioServiceImpl extends RemoteServiceServlet implements RStudioS
ScopeProvider.instance.set(currScope);
return toReturn;
}
-
+
private static boolean checkRStudioInstanceExistence(GCubeUser curUser, String hostedOn, List resources) {
for (ServiceEndpoint serviceEndpoint : resources)
if (serviceEndpoint.profile().runtime().hostedOn().equals(hostedOn)) {
- _log.info("**** The instance previously set for user " + curUser.getFullname() + " on " + hostedOn + " is still valid");
+ _log.info("---- checkRStudioServiceEndpointExistence: The instance previously set for user " + curUser.getFullname() + " on " + hostedOn + " is still valid");
return true;
}
return false;
}
+
+ private static boolean checkRStudioGCoreInstanceExistence(GCubeUser curUser, String hostedOn, List resources) {
+ for (GCoreEndpoint gcoreEndpoint : resources) {
+ String instance = extractGCoreEndpointHostAndPort(gcoreEndpoint);
+ if (instance.equalsIgnoreCase(hostedOn)) {
+ _log.info("**** checkRStudioGCoreInstanceExistence: The instance previously set for user " + curUser.getFullname() + " on " + hostedOn + " is still valid");
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static String extractGCoreEndpointHostAndPort(GCoreEndpoint resource) {
+ Collection eps = resource.profile().endpoints().asCollection();
+ for (Endpoint ep : eps)
+ if (ep.name().equalsIgnoreCase(RCONNECTOR_EntryName))
+ return new StringBuilder(ep.uri().getHost()).append(":").append(ep.uri().getPort()).toString();
+ return null;
+ }
}