Skip to content

Commit 040e16b

Browse files
authored
transactional importObject method; correct basePath construction in DeleteAIPPermissionTest. (#3596)
1 parent a327feb commit 040e16b

File tree

10 files changed

+196
-11
lines changed

10 files changed

+196
-11
lines changed

roda-core/roda-core-tests/src/main/java/org/roda/core/storage/DeleteAIPPermissionTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ public class DeleteAIPPermissionTest {
6565
private static LdapUtilityTestHelper ldapUtilityTestHelper;
6666

6767
@BeforeMethod
68-
public static void setUp() throws Exception {
69-
basePath = TestsHelper.createBaseTempDir(FileStorageServiceTest.class, true);
68+
public void setUp() throws Exception {
69+
basePath = TestsHelper.createBaseTempDir(this.getClass(), true);
7070
ldapUtilityTestHelper = new LdapUtilityTestHelper();
7171

7272
RodaCoreFactory.instantiateTest(true, true, true, true, true, false, false, ldapUtilityTestHelper.getLdapUtility());

roda-core/roda-core/src/main/java/org/roda/core/index/IndexModelObserver.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
import org.roda.core.data.exceptions.ReturnWithExceptions;
3434
import org.roda.core.data.utils.JsonUtils;
3535
import org.roda.core.data.v2.IsModelObject;
36+
import org.roda.core.data.v2.IsRODAObject;
37+
import org.roda.core.data.v2.LiteRODAObject;
3638
import org.roda.core.data.v2.common.OptionalWithCause;
3739
import org.roda.core.data.v2.disposal.confirmation.DisposalConfirmation;
3840
import org.roda.core.data.v2.disposal.schedule.DisposalSchedule;
@@ -79,8 +81,16 @@
7981
import org.roda.core.index.schema.collections.RiskCollection;
8082
import org.roda.core.index.utils.IterableIndexResult;
8183
import org.roda.core.index.utils.SolrUtils;
84+
import org.roda.core.model.LiteRODAObjectFactory;
8285
import org.roda.core.model.ModelObserver;
8386
import org.roda.core.model.ModelService;
87+
import org.roda.core.model.lites.ParsedAIPLite;
88+
import org.roda.core.model.lites.ParsedDIPFileLite;
89+
import org.roda.core.model.lites.ParsedDIPLite;
90+
import org.roda.core.model.lites.ParsedFileLite;
91+
import org.roda.core.model.lites.ParsedLite;
92+
import org.roda.core.model.lites.ParsedPreservationMetadataLite;
93+
import org.roda.core.model.lites.ParsedRepresentationLite;
8494
import org.roda.core.storage.Binary;
8595
import org.roda.core.storage.fs.FSUtils;
8696
import org.roda.core.util.IdUtils;
@@ -1488,4 +1498,70 @@ public ReturnWithExceptions<Void, ModelObserver> disposalConfirmationDeleted(Str
14881498
return deleteDocumentFromIndex(DisposalConfirmation.class, confirmationId);
14891499
}
14901500

1501+
public ReturnWithExceptions<Void, ModelObserver> liteRODAObjectCreated(LiteRODAObject liteRODAObject) {
1502+
ReturnWithExceptions<Void, ModelObserver> ret = new ReturnWithExceptions<>(this);
1503+
OptionalWithCause<IsRODAObject> liteObject = LiteRODAObjectFactory.get(model, liteRODAObject);
1504+
if (liteObject.isPresent()) {
1505+
IsRODAObject obj = liteObject.get();
1506+
if (obj instanceof AIP aip) {
1507+
ret.add(aipCreated(aip));
1508+
} else if (obj instanceof Representation rep) {
1509+
ret.add(representationCreated(rep));
1510+
} else if (obj instanceof File file) {
1511+
ret.add(fileCreated(file));
1512+
} else if (obj instanceof DIP dip) {
1513+
ret.add(dipCreated(dip, true));
1514+
} else if (obj instanceof DIPFile dipFile) {
1515+
ret.add(dipFileCreated(dipFile));
1516+
} else if (obj instanceof PreservationMetadata pm) {
1517+
ret.add(preservationMetadataCreated(pm));
1518+
}
1519+
}
1520+
return ret;
1521+
}
1522+
1523+
public ReturnWithExceptions<Void, ModelObserver> liteRODAObjectUpdated(LiteRODAObject liteRODAObject) {
1524+
ReturnWithExceptions<Void, ModelObserver> ret = new ReturnWithExceptions<>(this);
1525+
OptionalWithCause<IsRODAObject> liteObject = LiteRODAObjectFactory.get(model, liteRODAObject);
1526+
if (liteObject.isPresent()) {
1527+
IsRODAObject obj = liteObject.get();
1528+
if (obj instanceof AIP aip) {
1529+
ret.add(aipUpdated(aip));
1530+
} else if (obj instanceof Representation rep) {
1531+
ret.add(representationUpdated(rep));
1532+
} else if (obj instanceof File file) {
1533+
ret.add(fileUpdated(file));
1534+
} else if (obj instanceof DIP dip) {
1535+
ret.add(dipUpdated(dip, true));
1536+
} else if (obj instanceof DIPFile dipFile) {
1537+
ret.add(dipFileUpdated(dipFile));
1538+
} else if (obj instanceof PreservationMetadata pm) {
1539+
ret.add(preservationMetadataUpdated(pm));
1540+
}
1541+
}
1542+
return ret;
1543+
}
1544+
1545+
public ReturnWithExceptions<Void, ModelObserver> liteRODAObjectDeleted(LiteRODAObject liteRODAObject) {
1546+
ReturnWithExceptions<Void, ModelObserver> ret = new ReturnWithExceptions<>(this);
1547+
OptionalWithCause<ParsedLite> parsed = ParsedLite.parse(liteRODAObject);
1548+
if (parsed.isPresent()) {
1549+
ParsedLite lite = parsed.get();
1550+
if (lite instanceof ParsedAIPLite aip) {
1551+
ret.add(aipDeleted(aip.getId(), true));
1552+
1553+
} else if (lite instanceof ParsedRepresentationLite rep) {
1554+
ret.add(representationDeleted(rep.getAipId(), rep.getId(), true));
1555+
} else if (lite instanceof ParsedFileLite file) {
1556+
ret.add(fileDeleted(file.getAipId(), file.getRepresentationId(), file.getDirectoryPath(), file.getId(), true));
1557+
} else if (lite instanceof ParsedDIPLite dip) {
1558+
ret.add(dipDeleted(dip.getId(), true));
1559+
} else if (lite instanceof ParsedDIPFileLite dipFile) {
1560+
ret.add(dipFileDeleted(dipFile.getId(), dipFile.getDirectoryPath(), dipFile.getFileId()));
1561+
} else if (lite instanceof ParsedPreservationMetadataLite pm) {
1562+
ret.add(preservationMetadataDeleted(new PreservationMetadata(pm.getId(), pm.getType())));
1563+
}
1564+
}
1565+
return ret;
1566+
}
14911567
}

roda-core/roda-core/src/main/java/org/roda/core/model/DefaultModelService.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5059,6 +5059,17 @@ private ReturnWithExceptionsWrapper notifyObserversSafely(Function<ModelObserver
50595059
}
50605060
return wrapper;
50615061
}
5062+
public ReturnWithExceptionsWrapper notifyLiteRodaObjectCreated(LiteRODAObject object){
5063+
return notifyObserversSafely(observer -> observer.liteRODAObjectCreated(object));
5064+
}
5065+
5066+
public ReturnWithExceptionsWrapper notifyLiteRodaObjectUpdated(LiteRODAObject object){
5067+
return notifyObserversSafely(observer -> observer.liteRODAObjectUpdated(object));
5068+
}
5069+
5070+
public ReturnWithExceptionsWrapper notifyLiteRodaObjectDeleted(LiteRODAObject object){
5071+
return notifyObserversSafely(observer -> observer.liteRODAObjectUpdated(object));
5072+
}
50625073

50635074
@Override
50645075
public ReturnWithExceptionsWrapper notifyAipCreated(AIP aip) {
@@ -5647,10 +5658,23 @@ private static void clearSpecificIndexes(IndexService index, Class<IsRODAObject>
56475658
public void exportAll(StorageService toStorage) {
56485659
// TODO
56495660
}
5650-
5661+
56515662
@Override
5652-
public void importObject(IsRODAObject object, StorageService fromStorage) {
5653-
// TODO
5663+
public void importObject(ModelService fromModel, LiteRODAObject object, boolean replaceExisting)
5664+
throws RequestNotValidException, GenericException, NotFoundException, AuthorizationDeniedException,
5665+
AlreadyExistsException {
5666+
StoragePath toObjectPath = ModelUtils.getStoragePath(object);
5667+
boolean existsBeforeImport = getStorage().exists(toObjectPath);
5668+
5669+
getStorage().importObject(fromModel.getStorage(), object, toObjectPath, replaceExisting);
5670+
5671+
boolean notifyUpdate = existsBeforeImport && replaceExisting;
5672+
5673+
if (notifyUpdate) {
5674+
notifyLiteRodaObjectUpdated(object);
5675+
} else {
5676+
notifyLiteRodaObjectCreated(object);
5677+
}
56545678
}
56555679

56565680
@Override

roda-core/roda-core/src/main/java/org/roda/core/model/DefaultTransactionalModelService.java

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3924,10 +3924,23 @@ public void exportAll(StorageService toStorage) {
39243924
}
39253925

39263926
@Override
3927-
public void importObject(IsRODAObject object, StorageService fromStorage) {
3928-
TransactionalModelOperationLog operationLog = operationRegistry.registerOperation(object, OperationType.UPDATE);
3929-
getModelService().importObject(object, fromStorage);
3930-
operationRegistry.updateOperationState(operationLog, OperationState.SUCCESS);
3927+
public void importObject(ModelService fromModel, LiteRODAObject object, boolean replaceExisting)
3928+
throws RequestNotValidException, GenericException, NotFoundException, AuthorizationDeniedException,
3929+
AlreadyExistsException {
3930+
TransactionalModelOperationLog operationLog;
3931+
if (replaceExisting) {
3932+
operationLog = operationRegistry.registerOperation(object.getInfo(), OperationType.CREATE_OR_UPDATE);
3933+
} else {
3934+
operationLog = operationRegistry.registerOperation(object.getInfo(), OperationType.CREATE);
3935+
}
3936+
try {
3937+
getModelService().importObject(fromModel, object, replaceExisting);
3938+
operationRegistry.updateOperationState(operationLog, OperationState.SUCCESS);
3939+
} catch (RequestNotValidException | NotFoundException | AuthorizationDeniedException | AlreadyExistsException
3940+
| GenericException e) {
3941+
operationRegistry.updateOperationState(operationLog, OperationState.FAILURE);
3942+
throw e;
3943+
}
39313944
}
39323945

39333946
@Override

roda-core/roda-core/src/main/java/org/roda/core/model/ModelObserver.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.List;
1111

1212
import org.roda.core.data.exceptions.ReturnWithExceptions;
13+
import org.roda.core.data.v2.LiteRODAObject;
1314
import org.roda.core.data.v2.disposal.confirmation.DisposalConfirmation;
1415
import org.roda.core.data.v2.ip.AIP;
1516
import org.roda.core.data.v2.ip.DIP;
@@ -151,4 +152,10 @@ public ReturnWithExceptions<Void, ModelObserver> disposalConfirmationCreateOrUpd
151152
DisposalConfirmation confirmation);
152153

153154
public ReturnWithExceptions<Void, ModelObserver> disposalConfirmationDeleted(String confirmationId, boolean commit);
155+
156+
public ReturnWithExceptions<Void, ModelObserver> liteRODAObjectCreated(LiteRODAObject liteRODAObject);
157+
158+
public ReturnWithExceptions<Void, ModelObserver> liteRODAObjectUpdated(LiteRODAObject liteRODAObject);
159+
160+
public ReturnWithExceptions<Void, ModelObserver> liteRODAObjectDeleted(LiteRODAObject liteRODAObject);
154161
}

roda-core/roda-core/src/main/java/org/roda/core/model/ModelService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,8 @@ int importAll(IndexService index, final FileStorageService fromStorage, final bo
973973

974974
void exportAll(StorageService toStorage);
975975

976-
void importObject(IsRODAObject object, StorageService fromStorage);
976+
void importObject(ModelService fromModel, LiteRODAObject object, boolean replaceExisting) throws RequestNotValidException,
977+
GenericException, NotFoundException, AuthorizationDeniedException, AlreadyExistsException;
977978

978979
void exportObject(IsRODAObject object, StorageService toStorage, String... toPathPartials)
979980
throws RequestNotValidException, AuthorizationDeniedException, AlreadyExistsException, NotFoundException,

roda-core/roda-core/src/main/java/org/roda/core/storage/DefaultTransactionalStorageService.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.roda.core.data.exceptions.GenericException;
2929
import org.roda.core.data.exceptions.NotFoundException;
3030
import org.roda.core.data.exceptions.RequestNotValidException;
31+
import org.roda.core.data.v2.LiteRODAObject;
3132
import org.roda.core.data.v2.ip.StoragePath;
3233
import org.roda.core.entity.transaction.OperationState;
3334
import org.roda.core.entity.transaction.OperationType;
@@ -439,6 +440,31 @@ public void copy(StorageService fromService, StoragePath fromStoragePath, Path t
439440

440441
}
441442

443+
@Override
444+
public void importObject(StorageService fromService, LiteRODAObject object, StoragePath toStoragePath,
445+
boolean replaceExisting) throws AlreadyExistsException, GenericException, AuthorizationDeniedException,
446+
NotFoundException, RequestNotValidException {
447+
List<TransactionalStoragePathOperationLog> operationLogs;
448+
if (replaceExisting) {
449+
operationLogs = registerOperationForCopy(fromService, toStoragePath, toStoragePath,
450+
OperationType.CREATE_OR_UPDATE);
451+
} else {
452+
operationLogs = registerOperationForCopy(fromService, toStoragePath, toStoragePath, OperationType.CREATE);
453+
}
454+
try {
455+
stagingStorageService.importObject(fromService, object, toStoragePath, replaceExisting);
456+
for (TransactionalStoragePathOperationLog operationLog : operationLogs) {
457+
updateOperationState(operationLog, OperationState.SUCCESS);
458+
}
459+
} catch (AlreadyExistsException | NotFoundException | RequestNotValidException | GenericException
460+
| AuthorizationDeniedException e) {
461+
for (TransactionalStoragePathOperationLog operationLog : operationLogs) {
462+
updateOperationState(operationLog, OperationState.FAILURE);
463+
}
464+
throw e;
465+
}
466+
}
467+
442468
@Override
443469
public void move(StorageService fromService, StoragePath fromStoragePath, StoragePath toStoragePath)
444470
throws AlreadyExistsException, GenericException, RequestNotValidException, NotFoundException,
@@ -763,7 +789,8 @@ private void handleCreateUpdateOperation(StoragePath storagePath, String version
763789
if (Container.class.isAssignableFrom(rootEntity)) {
764790
mainStorageService.createContainer(storagePath);
765791
} else if (Directory.class.isAssignableFrom(rootEntity)) {
766-
mainStorageService.createDirectory(storagePath);
792+
if (!mainStorageService.exists(storagePath))
793+
mainStorageService.createDirectory(storagePath);
767794
} else {
768795
StorageServiceUtils.syncBetweenStorageServices(stagingStorageService, storagePath, mainStorageService,
769796
storagePath, getEntity(storagePath));

roda-core/roda-core/src/main/java/org/roda/core/storage/StorageService.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.roda.core.data.exceptions.GenericException;
1919
import org.roda.core.data.exceptions.NotFoundException;
2020
import org.roda.core.data.exceptions.RequestNotValidException;
21+
import org.roda.core.data.v2.LiteRODAObject;
2122
import org.roda.core.data.v2.ip.StoragePath;
2223

2324
/**
@@ -355,6 +356,12 @@ void copy(StorageService fromService, StoragePath fromStoragePath, StoragePath t
355356
void copy(StorageService fromService, StoragePath fromStoragePath, Path toPath, String resource,
356357
boolean replaceExisting) throws AlreadyExistsException, GenericException, AuthorizationDeniedException;
357358

359+
360+
default void importObject(StorageService fromService, LiteRODAObject object, StoragePath toStoragePath, boolean replaceExisting)
361+
throws AlreadyExistsException, GenericException, AuthorizationDeniedException, NotFoundException, RequestNotValidException {
362+
throw new UnsupportedOperationException("Not supported yet.");
363+
};
364+
358365
/**
359366
* Move resources from another (or the same) storage service.
360367
*

roda-core/roda-core/src/main/java/org/roda/core/storage/StorageServiceWrapper.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.roda.core.data.exceptions.GenericException;
2121
import org.roda.core.data.exceptions.NotFoundException;
2222
import org.roda.core.data.exceptions.RequestNotValidException;
23+
import org.roda.core.data.v2.LiteRODAObject;
2324
import org.roda.core.data.v2.ip.StoragePath;
2425

2526
public class StorageServiceWrapper implements StorageService {
@@ -185,6 +186,14 @@ public void copy(StorageService fromService, StoragePath fromStoragePath, Path t
185186
storageService.copy(fromService, fromStoragePath, toPath, resource, replaceExisting);
186187
}
187188

189+
@Override
190+
public void importObject(StorageService fromService, LiteRODAObject object, StoragePath toStoragePath,
191+
boolean replaceExisting) throws AlreadyExistsException, GenericException, AuthorizationDeniedException,
192+
NotFoundException, RequestNotValidException {
193+
RodaCoreFactory.checkIfWriteIsAllowedAndIfFalseThrowException(nodeType);
194+
storageService.importObject(fromService, object, toStoragePath, replaceExisting);
195+
}
196+
188197
@Override
189198
public void move(StorageService fromService, StoragePath fromStoragePath, StoragePath toStoragePath)
190199
throws AlreadyExistsException, GenericException, RequestNotValidException, NotFoundException,

roda-core/roda-core/src/main/java/org/roda/core/storage/fs/FileStorageService.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.roda.core.data.exceptions.NotFoundException;
3535
import org.roda.core.data.exceptions.RequestNotValidException;
3636
import org.roda.core.data.utils.JsonUtils;
37+
import org.roda.core.data.v2.LiteRODAObject;
3738
import org.roda.core.data.v2.ip.ShallowFile;
3839
import org.roda.core.data.v2.ip.ShallowFiles;
3940
import org.roda.core.data.v2.ip.StoragePath;
@@ -579,6 +580,26 @@ public void copy(StorageService fromService, StoragePath fromStoragePath, Path t
579580
}
580581
}
581582

583+
@Override
584+
public void importObject(StorageService fromService, LiteRODAObject object, StoragePath toStoragePath,
585+
boolean replaceExisting) throws AlreadyExistsException, GenericException, NotFoundException,
586+
AuthorizationDeniedException, RequestNotValidException {
587+
StoragePath fromPath = ModelUtils.getStoragePath(object);
588+
if (!fromService.exists(fromPath)) {
589+
throw new NotFoundException("Source Path does not exist: " + fromPath);
590+
}
591+
592+
if (exists(toStoragePath)) {
593+
if(replaceExisting) {
594+
// workaround
595+
deleteResource(toStoragePath);
596+
} else {
597+
throw new AlreadyExistsException("Destination already exists: " + toStoragePath);
598+
}
599+
}
600+
copy(fromService, fromPath, toStoragePath);
601+
}
602+
582603
@Override
583604
public void move(StorageService fromService, StoragePath fromStoragePath, StoragePath toStoragePath)
584605
throws AlreadyExistsException, GenericException, RequestNotValidException, NotFoundException,

0 commit comments

Comments
 (0)