diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component index c8eb499..2ade11b 100644 --- a/.settings/org.eclipse.wst.common.component +++ b/.settings/org.eclipse.wst.common.component @@ -1,37 +1,46 @@ - + + - + + - + + - + + - + + - + + - + + - + + - + + diff --git a/pom.xml b/pom.xml index 09221e2..3c0db93 100644 --- a/pom.xml +++ b/pom.xml @@ -104,6 +104,11 @@ common-authorization provided + + org.gcube.core + common-encryption + provided + org.gcube.common event-publisher-library diff --git a/src/main/java/org/gcube/portlets/user/bluecloud/DdasVreIntegration.java b/src/main/java/org/gcube/portlets/user/bluecloud/DdasVreIntegration.java index 16138cc..4f32f7d 100644 --- a/src/main/java/org/gcube/portlets/user/bluecloud/DdasVreIntegration.java +++ b/src/main/java/org/gcube/portlets/user/bluecloud/DdasVreIntegration.java @@ -2,6 +2,9 @@ package org.gcube.portlets.user.bluecloud; +import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; +import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -9,6 +12,7 @@ import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; +import java.util.List; import javax.portlet.PortletException; import javax.portlet.PortletRequestDispatcher; @@ -16,13 +20,19 @@ import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import javax.servlet.http.HttpServletRequest; +import org.gcube.common.encryption.encrypter.StringEncrypter; import org.gcube.common.portal.PortalContext; +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; +import org.gcube.common.scope.api.ScopeProvider; import org.gcube.oidc.rest.JWTToken; import org.gcube.oidc.rest.OpenIdConnectConfiguration; import org.gcube.oidc.rest.OpenIdConnectRESTHelper; import org.gcube.oidc.rest.OpenIdConnectRESTHelperException; import org.gcube.portal.oidc.lr62.LiferayOpenIdConnectConfiguration; import org.gcube.portal.oidc.lr62.OIDCUmaUtil; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager; import org.gcube.vomanagement.usermanagement.model.GCubeUser; @@ -44,7 +54,14 @@ import net.spy.memcached.MemcachedClient; public class DdasVreIntegration extends MVCPortlet { private static com.liferay.portal.kernel.log.Log log = LogFactoryUtil.getLog(DdasVreIntegration.class); //The Blue-Cloud DD&AS Service endpoint for feedback about downloads - public static final String BROKER_FEEDBACK_ENDPOINT = "https://data.blue-cloud.org/api/vre/download-ready"; + public static final String BROKERf_FEEDBACK_ENDPOINT = "https://data.blue-cloud.org/api/vre/download-ready"; + + + private static final String BC_BROKER_RESOURCE_NAME = "Blue-Cloud-DataDownloadAndAccess"; + private static final String CATEGORY_NAME = "Service"; + private static final String BROKER_LOGIN_PROPERTY_NAME = "login"; + private static final String BROKER_FEEDBACK_PROPERTY_NAME = "download-ready"; + public static final String CONDUCTOR_WORKFLOW_NAME = "da_cache_to_shub"; private static final int CONNECTION_TIMEOUT = 10000; @@ -104,19 +121,21 @@ public class DdasVreIntegration extends MVCPortlet { * @throws Exception */ private boolean sendRequestToConductor(JsonElement brokerRequest, GCubeUser currentUser, RenderRequest renderRequest) throws Exception { + + + - String callbackURLBrokerService = BROKER_FEEDBACK_ENDPOINT; String userEmail = currentUser.getEmail(); log.debug("current user email is + " + userEmail); + Callback theCallback = getVRECallbackURLFromServiceEndpoint(userEmail); HttpServletRequest httpReq = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(renderRequest)); String context = "/"+PortalContext.getConfiguration().getInfrastructureName(); JWTToken userUMAToken = OIDCUmaUtil.getUMAToken(httpReq, currentUser.getUsername(), context); - - ConductorRequestBean req = new ConductorRequestBean(userUMAToken.getAccessTokenString(), new Callback(new URL(callbackURLBrokerService), userEmail)); + ConductorRequestBean req = new ConductorRequestBean(userUMAToken.getAccessTokenString(), theCallback); Gson gson = new Gson(); JsonElement jsonElement = gson.toJsonTree(req); jsonElement.getAsJsonObject().add("descriptor", brokerRequest); //append the original request as descriptor object - System.out.println(jsonElement.toString()); + log.debug("\n\nsendRequestToConductor\n"+jsonElement.toString()); URL eventPublisherURL = new URL(PrefsPropsUtil.getString(PortalUtil.getDefaultCompanyId(), "d4science.event-broker-endpoint")); return doPost(jsonElement, new URL(eventPublisherURL+CONDUCTOR_WORKFLOW_NAME)); @@ -260,14 +279,20 @@ public class DdasVreIntegration extends MVCPortlet { @SuppressWarnings("unused") private class Callback { - URL url; - String email; - public Callback(URL url, String email) { + URL url; // BROKER_FEEDBACK_ENDPOINT + String email; //where to send the email with the result report + String username; //the username to use to login using bearer token method + String password; //the password to use to login using bearer token method + URL authorize_url; //the endpoint to login and start the oAuth2 Bearer Token flow with the above credentials + + public Callback(URL url, String email, String username, String password, URL authorize_url) { super(); this.url = url; this.email = email; + this.username = username; + this.password = password; + this.authorize_url = authorize_url; } - } @SuppressWarnings("unused") private class ConductorRequestBean { @@ -280,4 +305,67 @@ public class DdasVreIntegration extends MVCPortlet { } } + + /** + * Retrieve the vre callbac URL to pass to the broker service in the response from the endpoint resource on IS + * @throws Exception + */ + private Callback getVRECallbackURLFromServiceEndpoint(String userEmail){ + + String currentScope = ScopeProvider.instance.get(); + String infrastructure = "/"+PortalContext.getConfiguration().getInfrastructureName(); + ScopeProvider.instance.set(infrastructure); + try{ + SimpleQuery query = queryFor(ServiceEndpoint.class); + query.addCondition("$resource/Profile/Name/text() eq '"+ BC_BROKER_RESOURCE_NAME +"'"); + query.addCondition("$resource/Profile/Category/text() eq '"+ CATEGORY_NAME +"'"); + DiscoveryClient client = clientFor(ServiceEndpoint.class); + try { + List list = client.submit(query); + if (list.size() > 1) { + System.out.println("Too many Service Endpoints having name " + BC_BROKER_RESOURCE_NAME +" in this scope having Category " + CATEGORY_NAME); + } + else if (list.size() == 0){ + System.out.println("There is no Service Endpoint having name " + BC_BROKER_RESOURCE_NAME +" and Category " + CATEGORY_NAME + " in this context " + infrastructure); + } + else { + for (ServiceEndpoint res : list) { + AccessPoint[] accessPoints = (AccessPoint[]) res.profile().accessPoints().toArray(new AccessPoint[res.profile().accessPoints().size()]); + String username = null; + String password = null; + String brokerApiURL = null; + String brokerfeedbackEndpoint = null; + String brokerLoginEndpoint = null; + for (AccessPoint found : accessPoints) { + brokerApiURL = found.address(); + log.debug("\nBC DD&AS AccessPoint found URL:" + brokerApiURL); + username = found.username(); + String passEncrypted = found.password(); + password = StringEncrypter.getEncrypter().decrypt(passEncrypted); + for (ServiceEndpoint.Property prop : found.properties()) { + if (prop.name().compareTo(BROKER_FEEDBACK_PROPERTY_NAME) == 0) + brokerfeedbackEndpoint = prop.value(); + if (prop.name().compareTo(BROKER_LOGIN_PROPERTY_NAME) == 0) + brokerLoginEndpoint = prop.value(); + } + } + String brokerAPILoginURL = brokerApiURL + brokerLoginEndpoint; //https://data.blue-cloud.org/api + /login + String brokerFeedbackURL = brokerApiURL + brokerfeedbackEndpoint; //https://data.blue-cloud.org/api + /vre/download-ready + + Callback toReturn = new Callback(new URL(brokerFeedbackURL), userEmail, username, password, new URL(brokerAPILoginURL)); + return toReturn; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } catch(Exception e){ + log.error("There is no Service Endpoint having name: " + BC_BROKER_RESOURCE_NAME + " and Category " + CATEGORY_NAME + " on root context"); + }finally{ + ScopeProvider.instance.set(currentScope); + } + ScopeProvider.instance.set(currentScope); + return null; + } + }