package org.gcube.portlets.widgets.wsthreddssync.server; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.gcube.common.portal.PortalContext; import org.gcube.portal.wssynclibrary.shared.ItemNotSynched; import org.gcube.portal.wssynclibrary.shared.WorkspaceFolderLocked; import org.gcube.portal.wssynclibrary.shared.thredds.Sync_Status; import org.gcube.portal.wssynclibrary.shared.thredds.ThCatalogueBean; import org.gcube.portal.wssynclibrary.shared.thredds.ThSyncFolderDescriptor; import org.gcube.portal.wssynclibrary.shared.thredds.ThSyncStatus; import org.gcube.portal.wssynclibrary.shared.thredds.ThSynchFolderConfiguration; import org.gcube.portlets.widgets.wsthreddssync.client.rpc.ThreddsWorkspaceSyncService; import org.gcube.portlets.widgets.wsthreddssync.shared.GatewayRolesThredds; import org.gcube.portlets.widgets.wsthreddssync.shared.GcubeScope; import org.gcube.portlets.widgets.wsthreddssync.shared.GcubeScopeType; import org.gcube.portlets.widgets.wsthreddssync.shared.WsThreddsSynchFolderConfiguration; import org.gcube.portlets.widgets.wsthreddssync.shared.WsThreddsSynchFolderDescriptor; import org.gcube.vomanagement.usermanagement.GroupManager; import org.gcube.vomanagement.usermanagement.exception.GroupRetrievalFault; import org.gcube.vomanagement.usermanagement.exception.UserManagementSystemException; import org.gcube.vomanagement.usermanagement.exception.UserRetrievalFault; import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager; import org.gcube.vomanagement.usermanagement.model.GCubeGroup; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.gcube.vomanagement.usermanagement.model.GatewayRolesNames; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.gwt.user.server.rpc.RemoteServiceServlet; import com.liferay.portal.service.UserLocalServiceUtil; /** * The server side implementation of the RPC service. * * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it * Feb 14, 2018 */ @SuppressWarnings("serial") public class ThreddsWorkspaceSyncServiceImpl extends RemoteServiceServlet implements ThreddsWorkspaceSyncService { /** The logger. */ private static Logger logger = LoggerFactory.getLogger(ThreddsWorkspaceSyncServiceImpl.class); /** The sync thredds. */ private SyncronizeWithThredds syncThredds = null; /** * Gets the sync service. * * @return the sync service */ public synchronized SyncronizeWithThredds getSyncService() { if(syncThredds==null) syncThredds = new SyncronizeWithThredds(); return syncThredds; } /** * Checks if is within portal. * * @return true if you're running into the portal, false if in development */ public static boolean isWithinPortal() { try { UserLocalServiceUtil.getService(); return true; } catch (Exception ex) { logger.warn("Development Mode ON"); return false; } } /** * Gets the available THREDDS catalogues for target scope. * * @param targetFullScope the target scope * @return the available catalogues for scope * @throws Exception the exception */ //UPDATED @Override public List getAvailableCataloguesForScope(String targetFullScope) throws Exception { if(targetFullScope==null) throw new Exception("Invalid scope null"); List listCtlgs = null; try { GCubeUser user = PortalContext.getConfiguration().getCurrentUser(this.getThreadLocalRequest()); listCtlgs = getSyncService().getAvailableCatalogues(this.getThreadLocalRequest(), user, targetFullScope); logger.debug("Retuning "+listCtlgs.size()+" Catalogues for scope: "+targetFullScope); if(logger.isDebugEnabled()){ for (ThCatalogueBean thCatalogueBean : listCtlgs) { logger.debug(thCatalogueBean.toString()); } } }catch (Exception e) { logger.error("Error on checking available Catalogue in the scope: "+targetFullScope, e); } return listCtlgs; } /** * Checks if is item synched. * * @param folderId the folder id * @return the ws thredds synch folder descriptor * @throws WorkspaceFolderLocked the workspace folder locked * @throws Exception the exception */ /* (non-Javadoc) * @see org.gcube.portlets.widgets.wsthreddssync.client.rpc.ThreddsWorkspaceSyncService#isItemSynched(java.lang.String) */ //UPDATED @Override public WsThreddsSynchFolderDescriptor isItemSynched(String folderId) throws WorkspaceFolderLocked, Exception{ logger.debug("called isItemSynched for folderId: "+folderId); try { ThSyncFolderDescriptor theConfig = getSyncService().isItemSynched(folderId); if(theConfig!=null) { logger.info("Folder id: "+folderId+" is synched"); //String wsUserToken = PortalContext.getConfiguration().getCurrentUserToken(wsScope, user.getUsername()); //ThSyncFolderDescriptor serverFolderSync = getSyncService().checkItemSynched(folderId,wsScope,wsUserToken); //the status is not set here (into isItemSynched implementation). Sync_Status theStatus = null; WsThreddsSynchFolderDescriptor toWsThreddFolder = BeanConverter.toWsThreddsFolderConfig(theConfig, theStatus); logger.debug("isItemSynched for id: "+folderId +" returning: "+toWsThreddFolder); return toWsThreddFolder; } logger.info("Folder id: "+folderId+" is not synched, returning null descriptor"); return null; } catch (ItemNotSynched e) { logger.info("The folderId: "+folderId +" is not synched, returning null for "+WsThreddsSynchFolderDescriptor.class.getSimpleName()); return null; } catch (WorkspaceFolderLocked e) { logger.warn(e.getMessage() +", sending exception to client..."); throw new WorkspaceFolderLocked(e.getFolderId(), e.getMessage()); }catch (Exception e) { logger.info("Error on isItemSynched for folderId: "+folderId, e); throw new Exception(e); } } /** * Do sync folder. * * @param folderId the folder id * @param clientConfig the client config * @return the th sync status * @throws Exception the exception */ /* * (non-Javadoc) * * @see org.gcube.portlets.widgets.wsthreddssync.client.rpc. * ThreddsWorkspaceSyncService#doSyncFolder(java.lang.String, * org.gcube.portlets.widgets.wsthreddssync.shared. * WsThreddsSynchFolderDescriptor) */ //UPDATED @Override public ThSyncStatus doSyncFolder(final String folderId, WsThreddsSynchFolderConfiguration clientConfig) throws Exception { logger.info("Performing doSyncFolder method on id: " + folderId + ", config: " + clientConfig); try { GCubeUser user = PortalContext.getConfiguration().getCurrentUser(this.getThreadLocalRequest()); ThSynchFolderConfiguration config = null; if (clientConfig != null && clientConfig.getSelectedScope() != null) { config = BeanConverter.toThSynchFolderConfiguration(clientConfig, folderId, clientConfig.getSelectedScope().getScopeName()); logger.debug("Creating server config " + config); } // logger.info("Calling doSyncFolder on folderId: "+folderId +", config: "+config); // String wsScope = PortalContext.getConfiguration().getCurrentScope(this.getThreadLocalRequest()); // String wsUserToken = PortalContext.getConfiguration().getCurrentUserToken(wsScope, user.getUsername()); ThSyncStatus status = getSyncService().doSyncFolder(folderId, config, this.getThreadLocalRequest(), user); logger.debug("Returning for folderId " + folderId + " the syncStatus: " + status); return status; } catch (Exception e) { logger.error("Do sync Folder error: ", e); throw new Exception("Sorry, an error occurred during synchonization phase, try again later"); } } /** * Do sync folder. * * @param folderId the folder id * @return the th sync status * @throws Exception the exception */ /* * (non-Javadoc) * * @see org.gcube.portlets.widgets.wsthreddssync.client.rpc. * ThreddsWorkspaceSyncService#doSyncFolder(java.lang.String, * org.gcube.portlets.widgets.wsthreddssync.shared. * WsThreddsSynchFolderDescriptor) */ // Updated @Override public Boolean doUnSyncFolder(final String folderId) throws Exception { logger.info("Performing unsync on folder id: " + folderId); try { GCubeUser user = PortalContext.getConfiguration().getCurrentUser(this.getThreadLocalRequest()); ThSyncFolderDescriptor foldeDesr = getSyncService().isItemSynched(folderId); return getSyncService().doUnSync(folderId, true, foldeDesr.getConfiguration(), this.getThreadLocalRequest(), user); } catch (Exception e) { logger.error("Do un sync Folder error: ", e); throw new Exception( "Sorry, an error occurred on deleting sync configurations, refresh and try again later"); } } /** * Gets the list of Scopes (Root-VO, VOs and VREs) for user and the Thredds roles that user has in them. * * @return the VREs and Thredds roles for a given user * @throws Exception the exception */ @Override public Map getScopesWithThreddsRolesForLoggedUser() throws Exception{ logger.info("called getScopesWithThreddsRolesForLoggedUser"); GCubeUser user = null; Map mapScopesRoles = null; //DEV MODE if (!isWithinPortal()){ mapScopesRoles = new HashMap(); mapScopesRoles.put("/gcube/devsec/devVRE", GatewayRolesThredds.DATA_EDITOR); // mapScopesRoles.put( "/gcube", GatewayRolesThredds.THREDDS_PUBLISHER); // mapScopesRoles.put( "/gcube/devNext/NextNext", GatewayRolesThredds.THREDDS_PUBLISHER); return mapScopesRoles; } try { user = PortalContext.getConfiguration().getCurrentUser(this.getThreadLocalRequest()); mapScopesRoles = WsUtil.getScopesWithThreddsRolesForUser(user); logger.info("returning Map(scopes,roles): "+mapScopesRoles); return mapScopesRoles; }catch (Exception e) { String errorMsg = "An error occurred on checking user roles. Refresh the page and try again."; logger.error("An error occurred on checking user roles for user: "+user, e); throw new Exception(errorMsg); } } /** * Gets the list scope with the role Data-Manager for logged user. * * @return the list of manager scopes for logged user * @throws Exception the exception */ @Override public List getListOfDataManagerScopesForLoggedUser() throws Exception{ logger.info("called getListOfVREsForLoggedUser...: "); GCubeUser user = PortalContext.getConfiguration().getCurrentUser(this.getThreadLocalRequest()); long userId = user.getUserId(); // Instantiate the manager GroupManager groupManager = new LiferayGroupManager(); List listOfScopes = new ArrayList(); //DEV MODE if (!isWithinPortal()){ listOfScopes.add(new GcubeScope("devVRE", "/gcube/devsec/devVRE", GcubeScopeType.VRE)); listOfScopes.add(new GcubeScope("NextNext", "/gcube/devNext/NextNext", GcubeScopeType.VRE)); listOfScopes.add(new GcubeScope("devNext", "/gcube/devNext", GcubeScopeType.VO)); listOfScopes.add(new GcubeScope("devsec", "/gcube/devsec", GcubeScopeType.VO)); listOfScopes.add(new GcubeScope("gcube", "/gcube", GcubeScopeType.ROOT)); Collections.sort(listOfScopes); return listOfScopes; } try { String gatewayHostname = GenericUtils.getGatewayClientHostname(getThreadLocalRequest()); //list of Scopes filtered for gateway Set filteredGroupsForGatw = groupManager.listGroupsByUserAndSite(userId, gatewayHostname); //List listOfGroups = groupManager.listGroupsByUser(userId); List listOfGroups = new ArrayList(filteredGroupsForGatw); logger.info("list of VREs in the gateway "+gatewayHostname+" are "+listOfGroups.size()); for (GCubeGroup gCubeGroup : listOfGroups) { long groupId = gCubeGroup.getGroupId(); String fullScope = groupManager.getInfrastructureScope(groupId); logger.debug("For groupId: "+groupId+" got full scope: "+fullScope); GcubeScopeType scopeType=null; if(groupManager.isVRE(groupId)){ scopeType = GcubeScopeType.VRE; }else if(groupManager.isVO(groupId)){ scopeType = GcubeScopeType.VO; } // }else if(groupManager.isRootVO(gCubeGroup.getGroupId())){ // scopeType = GcubeScopeType.ROOT; // } if(scopeType!=null){ GatewayRolesThredds roles = WsUtil.getThreddsRoleFor(user, gCubeGroup); //Adding only the scope where the user has the THREDDS_ADMIN role GcubeScope gcubeScope = checkDataManagerCapacityAndThreddsCatalogue(roles, gCubeGroup.getGroupName(), fullScope, groupManager, scopeType); if(gcubeScope!=null) { listOfScopes.add(gcubeScope); } } } GCubeGroup theRootVO = groupManager.getRootVO(); GatewayRolesThredds roles = WsUtil.getThreddsRoleFor(user, theRootVO); String rootVOFullScope = groupManager.getInfrastructureScope(theRootVO.getGroupId()); ///ADDING THE ROOT SCOPE if the user has the THREDDS_ADMIN role in the ROOT-VO GcubeScope gcubeScope = checkDataManagerCapacityAndThreddsCatalogue(roles, theRootVO.getGroupName(), rootVOFullScope, groupManager, GcubeScopeType.ROOT); if(gcubeScope!=null) { listOfScopes.add(gcubeScope); } } catch (UserRetrievalFault | UserManagementSystemException | GroupRetrievalFault e) { logger.error("Error occurred server-side getting VRE folders: ", e); throw new Exception("Sorry, an error occurred server-side getting VRE folders, try again later"); } if(listOfScopes.isEmpty()) { throw new Exception("No scope detected with the needed role: "+GatewayRolesThredds.DATA_MANAGER.getRoleName()+". Contact the VRE manager or the portal administrator"); } Collections.sort(listOfScopes); logger.info("Returning list of allowed scope/s with: "+GatewayRolesThredds.DATA_MANAGER + " role/s: "+listOfScopes); return listOfScopes; } /** * Checks if for the input scope: * - the user has the role {@link GatewayRolesThredds.#THREDDS_ADMIN} * - the scope has an available THREDDS catalogue configured * * @param role the role * @param scopeName the scope name e.g. devVRE * @param fullScope the full scope e.g. /gcube/devsec/devVRE * @param groupManager the group manager * @param scopeType the scope type * @return the gcube scope {@link GcubeScope} if the two conditions (see description) are satisfied, null otherwise * @throws Exception the exception */ private GcubeScope checkDataManagerCapacityAndThreddsCatalogue(GatewayRolesThredds role, String scopeName, String fullScope, GroupManager groupManager, GcubeScopeType scopeType) throws Exception { logger.debug("checking Data-Manager capacity and THREEDS catalogues for role: "+role, "scope name: "+scopeName+", scope: "+fullScope + " scope type: "+scopeType); if(role!=null && role.getRoleName().equalsIgnoreCase(GatewayRolesNames.DATA_MANAGER.getRoleName())){ try { List list = getAvailableCataloguesForScope(fullScope); if(list!=null) { return new GcubeScope(scopeName, fullScope, scopeType); } }catch (Exception e) { logger.error("Error on checking available catalogue for scope: "+fullScope, e); } } return null; } // /** // * Register callback for id. // * // * @param folderId the folder id // * @throws Exception the exception // */ // private void registerCallbackForId(String folderId) throws Exception{ // GCubeUser user = PortalContext.getConfiguration().getCurrentUser(this.getThreadLocalRequest()); // String wsScope = PortalContext.getConfiguration().getCurrentScope(this.getThreadLocalRequest()); // String wsUserToken = PortalContext.getConfiguration().getCurrentUserToken(wsScope, user.getUsername()); // getSyncService().registerCallbackForId(folderId, wsScope, wsUserToken); // } /** * Monitor sync status. * * @param folderId the folder id * @return the th sync status * @throws ItemNotSynched the item not synched * @throws Exception the exception */ /* (non-Javadoc) * @see org.gcube.portlets.widgets.wsthreddssync.client.rpc.ThreddsWorkspaceSyncService#monitorSyncStatus(java.lang.String) */ @Override public ThSyncStatus monitorSyncStatus(String folderId) throws ItemNotSynched, Exception{ GCubeUser user = PortalContext.getConfiguration().getCurrentUser(this.getThreadLocalRequest()); String wsScope = PortalContext.getConfiguration().getCurrentScope(this.getThreadLocalRequest()); String wsUserToken = PortalContext.getConfiguration().getCurrentUserToken(wsScope, user.getUsername()); return getSyncService().monitorSyncStatus(folderId, wsScope, wsUserToken); } }