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();
}
/**
* 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

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
public SyncFolderDescriptor check(String folderId, boolean recursively) throws WorkspaceInteractionException, InternalException {
WorkspaceFolderManager manager=new WorkspaceFolderManager(folderId);
return manager.check(recursively);
return new GuardedMethod<SyncFolderDescriptor>(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<ProcessDescriptor>(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();
}