/** * */ package org.gcube.portlets.widgets.wsthreddssync.server; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.gcube.common.authorization.library.provider.SecurityTokenProvider; import org.gcube.common.authorization.library.provider.UmaJWTProvider; import org.gcube.common.portal.PortalContext; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.oidc.rest.JWTToken; import org.gcube.portal.oidc.lr62.OIDCUmaUtil; 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.portal.wssynclibrary.thredds.WorkspaceThreddsSynchronize; import org.gcube.vomanagement.usermanagement.model.GCubeUser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; // TODO: Auto-generated Javadoc /** * The Class SyncronizeWithThredds. * * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it * Feb 7, 2018 */ public class SyncronizeWithThredds { /** The logger. */ private Logger logger = LoggerFactory.getLogger(SyncronizeWithThredds.class); /** The workspace thredds synchronize. */ private WorkspaceThreddsSynchronize workspaceThreddsSynchronize; /** The Constant sdf. */ //private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss"); /** * Instantiates a new publish on thredds. * * @param wsScopeUserToken the ws scope user token * @param username the username * @param httpSession the http session */ public SyncronizeWithThredds() { this.workspaceThreddsSynchronize = WorkspaceThreddsSynchronize.getInstance(); } /** * Sets the context parameters. * * @param scope the scope * @param userToken the user token */ private void setContextParameters(String scope, String userToken) { logger.debug("Setting context parameters with scope: "+scope +", user token: "+userToken.substring(0,10)+"-MASKED-TOKEN"); ScopeProvider.instance.set(scope); SecurityTokenProvider.instance.set(userToken); } /** * Change context for UMA. * * @param httpRequest the http request * @param user the user * @param targetScope the target scope * @return the string representing the previous UMA Token read from {@link UmaJWTProvider#get()} */ private String changeContextForUMA(HttpServletRequest httpRequest, GCubeUser user, String targetScope) { logger.debug("Setting UMA context with target scope: "+targetScope +", user: "+user.getUsername()); String previousUMAToken = null; try { previousUMAToken=UmaJWTProvider.instance.get(); JWTToken umaToken = OIDCUmaUtil.getUMAToken(httpRequest, user.getUsername(), targetScope); setContextForUMA(umaToken.getRaw()); }catch (Exception e) { logger.warn("Error on set context for UMA: ",e); if(previousUMAToken!=null) { logger.info("Setting previous UMA Token: "+previousUMAToken.substring(0,10)+"-MASKED-TOKEN"); setContextForUMA(previousUMAToken); } } return previousUMAToken; } /** * Reset context for UMA. * * @param umaToken the uma token * @return the string */ private void setContextForUMA(String umaToken) { logger.info("called set context for UMA"); if(umaToken==null || umaToken.isEmpty()) { logger.info("Uma Token is null or empty, skipping operation"); return; } logger.info("Going to set UMA Token: "+umaToken.substring(0,10)+"-MASKED-TOKEN"); UmaJWTProvider.instance.set(umaToken); logger.debug("UmaJWTProvider instance set performed to : "+umaToken.substring(0,10)+"-MASKED-TOKEN"); } /** * Do sync folder. * * @param folderId the folder id * @param thConfig the th config * @param scope the scope * @param userToken the user token * @return the th sync status * @throws Exception the exception */ public synchronized ThSyncStatus doSyncFolder(final String folderId, ThSynchFolderConfiguration thConfig, String scope, String userToken) throws Exception{ logger.debug("Perfoming doSynFolder on folderId: "+folderId); boolean firstSync = false; try { setContextParameters(scope, userToken); ThSyncFolderDescriptor folder = workspaceThreddsSynchronize.checkItemSynched(folderId); }catch (ItemNotSynched e) { firstSync = true; // TODO: handle exception }catch (Exception e) { logger.error("Error on check item sync: ",e); throw new Exception("Sorry an error occurred during folder publishing, refresh and try again"); } try{ if(firstSync) { if(thConfig==null) { throw new Exception("A valid folder configuration must be provided to perform the synchronization"); } logger.info("First sync setting synchronized folder configuration: "+thConfig); workspaceThreddsSynchronize.setSynchronizedFolder(thConfig, folderId); } logger.info("Calling do sync on folder id: "+folderId); return workspaceThreddsSynchronize.doSync(folderId); //SessionUtil.setTransferPublishingOnThredds(httpSession, status); }catch (Exception e) { logger.error("Error on do sync: ",e); throw new Exception(e.getMessage() +", refresh and try again"); } } /** * Gets the synched status from item property. * * @param folderId the folder id * @param scope the scope * @param username the username * @return the synched status from item property * @throws Exception the exception */ public Sync_Status getSynchedStatusFromItemProperty(String folderId, String scope, String username) throws Exception{ try { try { ScopeProvider.instance.set(scope); return workspaceThreddsSynchronize.getSynchedStatusFromItemProperty(folderId, username); }catch (ItemNotSynched e) { logger.info("The folder id: "+folderId +" is not synched returning null as "+Sync_Status.class.getSimpleName()); return null; } }catch (Exception e) { logger.error("Error on getSynchedStatusFromItemProperty for id: "+folderId, e); throw new Exception("Sorry, an error occurred during read sync status from HL properties, try again later"); } } /** * Checks if is item synched. * * @param folderId the folder id * @param scope the scope * @param username the username * @return true, if is item synched * @throws ItemNotSynched the item not synched * @throws Exception the exception */ public boolean isItemSynched(String folderId, String scope, String username) throws ItemNotSynched, Exception{ Sync_Status value = getSynchedStatusFromItemProperty(folderId, scope, username); if(value!=null) return true; return false; } /** * Check item synched. * * @param folderId the folder id * @param scope the scope * @param userToken the user token * @return the th sync folder descriptor * @throws ItemNotSynched the item not synched * @throws WorkspaceFolderLocked the workspace folder locked * @throws Exception the exception */ public ThSyncFolderDescriptor checkItemSynched(String folderId, String scope, String userToken) throws ItemNotSynched, WorkspaceFolderLocked, Exception{ setContextParameters(scope, userToken); return workspaceThreddsSynchronize.checkItemSynched(folderId); } /** * Gets the sync status. * * @param itemId the item id * @param scope the scope * @param userToken the user token * @return the sync status * @throws ItemNotSynched the item not synched * @throws Exception the exception */ public ThSyncStatus monitorSyncStatus(String itemId, String scope, String userToken) throws ItemNotSynched, Exception{ setContextParameters(scope, userToken); return workspaceThreddsSynchronize.monitorSyncStatus(itemId); } /** * Do un sync. * * @param folderId the folder id * @param deleteRemoteContent the delete remote content * @param scope the scope * @param userToken the user token * @return the boolean * @throws Exception the exception */ public Boolean doUnSync(String folderId, boolean deleteRemoteContent, String scope, String userToken) throws Exception { setContextParameters(scope, userToken); return workspaceThreddsSynchronize.doUnSync(folderId, deleteRemoteContent); } /** * Register callback for id. * * @param folderId the folder id * @param scope the scope * @param userToken the user token * @throws Exception the exception */ public void registerCallbackForId(String folderId, String scope, String userToken) throws Exception { setContextParameters(scope, userToken); workspaceThreddsSynchronize.registerCallbackForId(folderId); } /** * Gets the available catalogues. * * @param httpRequest the http request * @param user the user * @param targetScope the target scope * @return the available catalogues * @throws Exception the exception */ public List getAvailableCatalogues(HttpServletRequest httpRequest, GCubeUser user, String targetScope) throws Exception { String originalScope = null; String originalToken = null; String previousUmaToken = null; List listCatalogues = null; try { // context switch for Uma token previousUmaToken = changeContextForUMA(httpRequest, user, targetScope); // context switch for gcube-token and scope PortalContext pConfig = PortalContext.getConfiguration(); String wsScope = pConfig.getCurrentScope(httpRequest); String wsUserToken = pConfig.getCurrentUserToken(wsScope, user.getUsername()); // Thread Local contexts originalScope = wsScope; originalToken = wsUserToken; // getting token into target scope String targetScopeUserToken = PortalContext.getConfiguration().getCurrentUserToken(targetScope, user.getUsername()); setContextParameters(targetScope, targetScopeUserToken); // calling the engine listCatalogues = workspaceThreddsSynchronize.getAvailableCatalogues(); } catch (Exception e) { logger.error("Error on getting available Catalogues in the scope: " + targetScope, e); } finally { // resetting UMA token in the WS scope setContextForUMA(previousUmaToken); if (originalScope != null && originalScope.compareTo(targetScope) != 0) { logger.info("Resetting the scope: " + originalScope + " which was original WS context"); ScopeProvider.instance.set(originalScope); if (originalToken != null) { logger.info("Resetting the user token: " + originalToken.substring(0, 10) + "-MASKED-TOKEN which was original WS context"); SecurityTokenProvider.instance.set(originalToken); } } } return listCatalogues; } }