Guarded Methods

This commit is contained in:
Fabio Sinibaldi 2021-05-07 16:49:14 +02:00
parent ba5bdd8fff
commit 0c94a1578b
3 changed files with 148 additions and 54 deletions

View File

@ -23,13 +23,30 @@ public interface SyncEngine {
return SynchEngineImpl.get(); return SynchEngineImpl.get();
} }
/**
* Checked Access Method
*/
public SyncFolderDescriptor check(String folderId, boolean recursively) throws WorkspaceInteractionException, InternalException; public SyncFolderDescriptor check(String folderId, boolean recursively) throws WorkspaceInteractionException, InternalException;
public void registerCallBack(String folderId,SyncOperationCallBack callback) throws ProcessNotFoundException; public void registerCallBack(String folderId,SyncOperationCallBack callback) throws ProcessNotFoundException;
/**
* Checked Access Method
*/
public ProcessDescriptor doSync(String folderId) throws WorkspaceInteractionException, InternalException; 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; public void setSynchronizedFolder(SynchFolderConfiguration config,String folderId) throws WorkspaceInteractionException, InternalException;
/**
* Checked Access Method
*/
public void unsetSynchronizedFolder(String folderId,boolean deleteRemoteContent) throws WorkspaceInteractionException, InternalException; public void unsetSynchronizedFolder(String folderId,boolean deleteRemoteContent) throws WorkspaceInteractionException, InternalException;
public SynchronizedElementInfo getInfo(String elementId); public SynchronizedElementInfo getInfo(String elementId);
@ -37,8 +54,9 @@ public interface SyncEngine {
/** /**
* Checked Access Method * 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 * Checked Access Method

View File

@ -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<T> {
@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<T> 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;
}

View File

@ -121,8 +121,13 @@ public class SynchEngineImpl implements SyncEngine{
@Override @Override
public SyncFolderDescriptor check(String folderId, boolean recursively) throws WorkspaceInteractionException, InternalException { public SyncFolderDescriptor check(String folderId, boolean recursively) throws WorkspaceInteractionException, InternalException {
WorkspaceFolderManager manager=new WorkspaceFolderManager(folderId); return new GuardedMethod<SyncFolderDescriptor>(folderId) {
return manager.check(recursively); @Override
protected SyncFolderDescriptor run() throws WorkspaceInteractionException, InternalException, Exception {
WorkspaceFolderManager manager=getManager();
return manager.check(recursively);
}
}.execute().getResult();
} }
@Override @Override
@ -133,37 +138,45 @@ public class SynchEngineImpl implements SyncEngine{
@Override @Override
public ProcessDescriptor doSync(String folderId) throws WorkspaceInteractionException, InternalException { public ProcessDescriptor doSync(String folderId) throws WorkspaceInteractionException, InternalException {
User user=Security.getCurrent(); return new GuardedMethod<ProcessDescriptor>(folderId) {
log.info("User {} requested syncronization of {}",user,folderId); @Override
if(localProcesses.containsKey(folderId)) { protected ProcessDescriptor run() throws ProcessNotFoundException, WorkspaceInteractionException, InternalException {
ProcessDescriptor toReturn=localProcesses.get(folderId).getDescriptor(); User user=Security.getCurrent();
log.info("Returning ongoing process {} ",toReturn); log.info("User {} requested syncronization of {}",user,folderId);
return toReturn; if(localProcesses.containsKey(folderId)) {
ProcessDescriptor toReturn=localProcesses.get(folderId).getDescriptor();
log.info("Returning ongoing process {} ",toReturn);
return toReturn;
} }
else { else {
WorkspaceFolderManager manager=new WorkspaceFolderManager(folderId); WorkspaceFolderManager manager=getManager();
if (!manager.isSynched()) throw new WorkspaceNotSynchedException("Folder "+folderId+" is not configured for synchronization."); 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.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"); 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);
//NB THROWS SECURITY EXCEPTIONS Process toLaunch=new Process(user,folderId,completionCallback);
Security.checkOperator(manager.getSynchConfiguration()); localProcesses.put(folderId, toLaunch);
initializationExecutor.submit(new ProcessInitializationThread(toLaunch,synchronizationExecutor));
log.info("User {} is triggering synch for {} ",user,folderId); return toLaunch.getDescriptor();
}
Process toLaunch=new Process(user,folderId,completionCallback); }
localProcesses.put(folderId, toLaunch); }.execute().getResult();
initializationExecutor.submit(new ProcessInitializationThread(toLaunch,synchronizationExecutor));
return toLaunch.getDescriptor();
}
} }
@Override @Override
public void stopSynch(String folderId) throws ProcessNotFoundException { public void stopSynch(String folderId) throws ProcessNotFoundException, WorkspaceInteractionException, InternalException {
if(!localProcesses.containsKey(folderId)) throw new ProcessNotFoundException(folderId+" is not under local processes"); new GuardedMethod(folderId) {
localProcesses.get(folderId).cancel(); @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 @Override
public void unsetSynchronizedFolder(String folderId,boolean deleteRemoteContent) throws WorkspaceInteractionException, InternalException { 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 @Override
@ -190,23 +209,29 @@ public class SynchEngineImpl implements SyncEngine{
} }
@Override @Override
public void updateCatalogFile(String folderId, File toUpdate) throws InternalException { public void updateCatalogFile(String folderId, File toUpdate) throws InternalException, WorkspaceInteractionException {
File previousCatalogFile=null;
try { new GuardedMethod(folderId) {
WorkspaceFolderManager manager=new WorkspaceFolderManager(folderId); @Override
Security.checkOperator(manager.getSynchConfiguration()); protected Object run() throws Exception {
previousCatalogFile=manager.loadCatalogFile(); try {
String lockId=UUID.randomUUID().toString(); log.warn("Forcing unlock of {} ",folderId);
manager.lock(lockId); WorkspaceFolderManager manager=getManager();
manager.updateCatalogFile(toUpdate); File previousCatalogFile=manager.loadCatalogFile();
manager.unlock(lockId); String lockId=UUID.randomUUID().toString();
}catch(SecurityException e) { manager.lock(lockId);
throw e; manager.updateCatalogFile(toUpdate);
}catch(Throwable t) { manager.unlock(lockId);
log.warn("Unable to update catalogFile for {}. Trying to restore previous one..",folderId,t); return null;
throw new InternalException("Unable to restore previous catalog.",t); }catch(SecurityException e) {
//TODO try to restore previous catalog 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 @Override
@ -231,10 +256,14 @@ public class SynchEngineImpl implements SyncEngine{
@Override @Override
public void forceUnlock(String folderId) throws InternalException, WorkspaceInteractionException { public void forceUnlock(String folderId) throws InternalException, WorkspaceInteractionException {
log.warn("Forcing unlock of {} ",folderId); new GuardedMethod(folderId) {
WorkspaceFolderManager manager=new WorkspaceFolderManager(folderId); @Override
Security.checkOperator(manager.getSynchConfiguration()); protected Object run() throws WorkspaceInteractionException, InternalException {
manager.forceUnlock(); log.warn("Forcing unlock of {} ",folderId);
getManager().forceUnlock();
return null;
}
}.execute();
} }