Feature #18993 RStudio Wrapper portlet to support double queries
This commit is contained in:
parent
6cbb9bf96f
commit
0c2ecf2047
18
.classpath
18
.classpath
|
@ -1,18 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/rstudio-wrapper-portlet-1.3.1-SNAPSHOT/WEB-INF/classes" path="src/main/java">
|
||||
<classpathentry kind="src" output="target/rstudio-wrapper-portlet-1.4.0-SNAPSHOT/WEB-INF/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/rstudio-wrapper-portlet-1.3.1-SNAPSHOT/WEB-INF/classes" path="target/generated-sources/gwt">
|
||||
<classpathentry kind="src" output="target/rstudio-wrapper-portlet-1.4.0-SNAPSHOT/WEB-INF/classes" path="target/generated-sources/gwt">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/rstudio-wrapper-portlet-1.3.1-SNAPSHOT/WEB-INF/classes" path="src/main/resources">
|
||||
<classpathentry excluding="**" kind="src" output="target/rstudio-wrapper-portlet-1.4.0-SNAPSHOT/WEB-INF/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
|
@ -30,16 +30,16 @@
|
|||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/rstudio-wrapper-portlet-1.3.1-SNAPSHOT/WEB-INF/classes"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="owner.project.facets" value="java"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/rstudio-wrapper-portlet-1.4.0-SNAPSHOT/WEB-INF/classes"/>
|
||||
</classpath>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<fixed facet="wst.jsdt.web"/>
|
||||
<installed facet="java" version="1.7"/>
|
||||
<installed facet="jst.web" version="3.0"/>
|
||||
<installed facet="wst.jsdt.web" version="1.0"/>
|
||||
<installed facet="jst.jaxrs" version="2.0"/>
|
||||
<installed facet="liferay.portlet" version="6.2"/>
|
||||
<installed facet="com.gwtplugins.gwt.facet" version="1.0"/>
|
||||
<installed facet="java" version="1.8"/>
|
||||
</faceted-project>
|
||||
|
|
8
pom.xml
8
pom.xml
|
@ -24,10 +24,10 @@
|
|||
<distroDirectory>distro</distroDirectory>
|
||||
<liferay.version>6.2.5</liferay.version>
|
||||
<liferay.maven.plugin.version>6.2.10.12</liferay.maven.plugin.version>
|
||||
<liferay.auto.deploy.dir>/Users/massi/portal/liferay-portal-6.2-ce-ga6/deploy</liferay.auto.deploy.dir>
|
||||
<liferay.app.server.deploy.dir>/Users/massi/portal/liferay-portal-6.2-ce-ga6/tomcat-7.0.62/webapps</liferay.app.server.deploy.dir>
|
||||
<liferay.app.server.lib.global.dir>/Users/massi/portal/liferay-portal-6.2-ce-ga6/tomcat-7.0.62/lib/ext</liferay.app.server.lib.global.dir>
|
||||
<liferay.app.server.portal.dir>/Users/massi/portal/liferay-portal-6.2-ce-ga6/tomcat-7.0.62/webapps/ROOT</liferay.app.server.portal.dir>
|
||||
<liferay.auto.deploy.dir>${system.CATALINA_HOME}/../deploy</liferay.auto.deploy.dir>
|
||||
<liferay.app.server.deploy.dir>${system.CATALINA_HOME}/webapps</liferay.app.server.deploy.dir>
|
||||
<liferay.app.server.lib.global.dir>${system.CATALINA_HOME}/lib/ext</liferay.app.server.lib.global.dir>
|
||||
<liferay.app.server.portal.dir>${system.CATALINA_HOME}/webapps/ROOT</liferay.app.server.portal.dir>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
|
|
@ -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<ServiceEndpoint> 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<GCoreEndpoint> 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<String, Integer> rStudioDistributionMap = new HashMap<>();
|
||||
for (GCoreEndpoint res : gCoreResources) {
|
||||
String hostedOn = extractGCoreEndpointHostAndPort(res);
|
||||
rStudioDistributionMap.put(hostedOn, 0);
|
||||
}
|
||||
List<GCubeUser> 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<GCoreEndpoint> 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<GCoreEndpoint> client = clientFor(GCoreEndpoint.class);
|
||||
List<GCoreEndpoint> 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<ServiceEndpoint> 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<GCoreEndpoint> 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<Endpoint> 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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue