diff --git a/src/main/java/org/gcube/usecases/ws/thredds/SyncEngine.java b/src/main/java/org/gcube/usecases/ws/thredds/SyncEngine.java index 4b6f207..ba899ff 100644 --- a/src/main/java/org/gcube/usecases/ws/thredds/SyncEngine.java +++ b/src/main/java/org/gcube/usecases/ws/thredds/SyncEngine.java @@ -23,13 +23,30 @@ public interface SyncEngine { return SynchEngineImpl.get(); } - + /** + * Checked Access Method + */ public SyncFolderDescriptor check(String folderId, boolean recursively) throws WorkspaceInteractionException, InternalException; public void registerCallBack(String folderId,SyncOperationCallBack callback) throws ProcessNotFoundException; + + /** + * Checked Access Method + */ public ProcessDescriptor doSync(String folderId) throws WorkspaceInteractionException, InternalException; - public void stopSynch(String folderId) throws ProcessNotFoundException; + + /** + * Checked Access Method + * @throws InternalException + * @throws WorkspaceInteractionException + */ + public void stopSynch(String folderId) throws ProcessNotFoundException, WorkspaceInteractionException, InternalException; + public void setSynchronizedFolder(SynchFolderConfiguration config,String folderId) throws WorkspaceInteractionException, InternalException; + + /** + * Checked Access Method + */ public void unsetSynchronizedFolder(String folderId,boolean deleteRemoteContent) throws WorkspaceInteractionException, InternalException; public SynchronizedElementInfo getInfo(String elementId); @@ -37,8 +54,9 @@ public interface SyncEngine { /** * Checked Access Method + * @throws WorkspaceInteractionException */ - public void updateCatalogFile(String folderId, File toUpdate) throws InternalException; + public void updateCatalogFile(String folderId, File toUpdate) throws InternalException, WorkspaceInteractionException; /** * Checked Access Method diff --git a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/GuardedMethod.java b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/GuardedMethod.java new file mode 100644 index 0000000..24c5be1 --- /dev/null +++ b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/GuardedMethod.java @@ -0,0 +1,47 @@ +package org.gcube.usecases.ws.thredds.engine.impl; + +import org.gcube.usecases.ws.thredds.engine.impl.security.Security; +import org.gcube.usecases.ws.thredds.faults.InternalException; +import org.gcube.usecases.ws.thredds.faults.WorkspaceInteractionException; +import org.gcube.usecases.ws.thredds.model.SynchFolderConfiguration; + +import lombok.Getter; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public abstract class GuardedMethod { + + @Getter + private WorkspaceFolderManager manager; + @Getter + private SynchFolderConfiguration configuration; + + @Getter + private String folderId; + @Getter + private T result=null; + + public GuardedMethod(String folderId) throws WorkspaceInteractionException { + this.folderId=folderId; + manager=new WorkspaceFolderManager(folderId); + configuration=manager.getSynchConfiguration(); + Security.checkOperator(configuration); + } + + + public GuardedMethod execute() throws WorkspaceInteractionException,InternalException{ + try { + result=run(); + return this; + }catch(WorkspaceInteractionException|InternalException e) { + throw e; + }catch(Throwable t) { + log.error("Unexpected error ",t); + throw new InternalException("Unexpected internal error", t); + } + + } + + protected abstract T run() throws WorkspaceInteractionException,InternalException,Exception; + +} diff --git a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/SynchEngineImpl.java b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/SynchEngineImpl.java index b987dd3..0b46e05 100644 --- a/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/SynchEngineImpl.java +++ b/src/main/java/org/gcube/usecases/ws/thredds/engine/impl/SynchEngineImpl.java @@ -121,8 +121,13 @@ public class SynchEngineImpl implements SyncEngine{ @Override public SyncFolderDescriptor check(String folderId, boolean recursively) throws WorkspaceInteractionException, InternalException { - WorkspaceFolderManager manager=new WorkspaceFolderManager(folderId); - return manager.check(recursively); + return new GuardedMethod(folderId) { + @Override + protected SyncFolderDescriptor run() throws WorkspaceInteractionException, InternalException, Exception { + WorkspaceFolderManager manager=getManager(); + return manager.check(recursively); + } + }.execute().getResult(); } @Override @@ -133,37 +138,45 @@ public class SynchEngineImpl implements SyncEngine{ @Override public ProcessDescriptor doSync(String folderId) throws WorkspaceInteractionException, InternalException { - User user=Security.getCurrent(); - log.info("User {} requested syncronization of {}",user,folderId); - if(localProcesses.containsKey(folderId)) { - ProcessDescriptor toReturn=localProcesses.get(folderId).getDescriptor(); - log.info("Returning ongoing process {} ",toReturn); - return toReturn; - - } - else { - WorkspaceFolderManager manager=new WorkspaceFolderManager(folderId); - if (!manager.isSynched()) throw new WorkspaceNotSynchedException("Folder "+folderId+" is not configured for synchronization."); - if(manager.isLocked()) throw new WorkspaceLockedException("Folder "+folderId+"is locked by an external process."); - if(!manager.isRoot()) throw new WorkspaceFolderNotRootException("Unable to launch synch operation. Folder "+folderId+" is not root configuration"); - - - //NB THROWS SECURITY EXCEPTIONS - Security.checkOperator(manager.getSynchConfiguration()); + return new GuardedMethod(folderId) { + @Override + protected ProcessDescriptor run() throws ProcessNotFoundException, WorkspaceInteractionException, InternalException { + User user=Security.getCurrent(); + log.info("User {} requested syncronization of {}",user,folderId); + if(localProcesses.containsKey(folderId)) { + ProcessDescriptor toReturn=localProcesses.get(folderId).getDescriptor(); + log.info("Returning ongoing process {} ",toReturn); + return toReturn; - log.info("User {} is triggering synch for {} ",user,folderId); - - Process toLaunch=new Process(user,folderId,completionCallback); - localProcesses.put(folderId, toLaunch); - initializationExecutor.submit(new ProcessInitializationThread(toLaunch,synchronizationExecutor)); - return toLaunch.getDescriptor(); - } + } + else { + WorkspaceFolderManager manager=getManager(); + if (!manager.isSynched()) throw new WorkspaceNotSynchedException("Folder "+folderId+" is not configured for synchronization."); + if(manager.isLocked()) throw new WorkspaceLockedException("Folder "+folderId+"is locked by an external process."); + if(!manager.isRoot()) throw new WorkspaceFolderNotRootException("Unable to launch synch operation. Folder "+folderId+" is not root configuration"); + + log.info("User {} is triggering synch for {} ",user,folderId); + + Process toLaunch=new Process(user,folderId,completionCallback); + localProcesses.put(folderId, toLaunch); + initializationExecutor.submit(new ProcessInitializationThread(toLaunch,synchronizationExecutor)); + return toLaunch.getDescriptor(); + } + } + }.execute().getResult(); } @Override - public void stopSynch(String folderId) throws ProcessNotFoundException { - if(!localProcesses.containsKey(folderId)) throw new ProcessNotFoundException(folderId+" is not under local processes"); - localProcesses.get(folderId).cancel(); + public void stopSynch(String folderId) throws ProcessNotFoundException, WorkspaceInteractionException, InternalException { + new GuardedMethod(folderId) { + @Override + protected Object run() throws ProcessNotFoundException { + if(!localProcesses.containsKey(folderId)) throw new ProcessNotFoundException(folderId+" is not under local processes"); + localProcesses.get(folderId).cancel(); + return null; + } + }.execute(); + } @@ -181,7 +194,13 @@ public class SynchEngineImpl implements SyncEngine{ @Override public void unsetSynchronizedFolder(String folderId,boolean deleteRemoteContent) throws WorkspaceInteractionException, InternalException { - new WorkspaceFolderManager(folderId).dismiss(deleteRemoteContent); + new GuardedMethod(folderId) { + @Override + protected Object run() throws WorkspaceInteractionException, InternalException { + getManager().dismiss(deleteRemoteContent); + return null; + } + }.execute(); } @Override @@ -190,23 +209,29 @@ public class SynchEngineImpl implements SyncEngine{ } @Override - public void updateCatalogFile(String folderId, File toUpdate) throws InternalException { - File previousCatalogFile=null; - try { - WorkspaceFolderManager manager=new WorkspaceFolderManager(folderId); - Security.checkOperator(manager.getSynchConfiguration()); - previousCatalogFile=manager.loadCatalogFile(); - String lockId=UUID.randomUUID().toString(); - manager.lock(lockId); - manager.updateCatalogFile(toUpdate); - manager.unlock(lockId); - }catch(SecurityException e) { - throw e; - }catch(Throwable t) { - log.warn("Unable to update catalogFile for {}. Trying to restore previous one..",folderId,t); - throw new InternalException("Unable to restore previous catalog.",t); - //TODO try to restore previous catalog - } + public void updateCatalogFile(String folderId, File toUpdate) throws InternalException, WorkspaceInteractionException { + + new GuardedMethod(folderId) { + @Override + protected Object run() throws Exception { + try { + log.warn("Forcing unlock of {} ",folderId); + WorkspaceFolderManager manager=getManager(); + File previousCatalogFile=manager.loadCatalogFile(); + String lockId=UUID.randomUUID().toString(); + manager.lock(lockId); + manager.updateCatalogFile(toUpdate); + manager.unlock(lockId); + return null; + }catch(SecurityException e) { + throw e; + }catch(Throwable t) { + log.warn("Unable to update catalogFile for {}. Trying to restore previous one..",folderId,t); + throw new InternalException("Unable to restore previous catalog.",t); + //TODO try to restore previous catalog + } + } + }.execute(); } @Override @@ -231,10 +256,14 @@ public class SynchEngineImpl implements SyncEngine{ @Override public void forceUnlock(String folderId) throws InternalException, WorkspaceInteractionException { - log.warn("Forcing unlock of {} ",folderId); - WorkspaceFolderManager manager=new WorkspaceFolderManager(folderId); - Security.checkOperator(manager.getSynchConfiguration()); - manager.forceUnlock(); + new GuardedMethod(folderId) { + @Override + protected Object run() throws WorkspaceInteractionException, InternalException { + log.warn("Forcing unlock of {} ",folderId); + getManager().forceUnlock(); + return null; + } + }.execute(); }