Mercurial > hg > orthanc
changeset 5464:38f1d06875ad pg-transactions
delete attachment in case of same instance being uploaded multiple times at the same time
author | Alain Mazy <am@osimis.io> |
---|---|
date | Tue, 12 Dec 2023 17:20:10 +0100 |
parents | 46ed738c3e5d |
children | 2829889bfa57 |
files | OrthancFramework/Resources/CodeGeneration/ErrorCodes.json OrthancFramework/Sources/Enumerations.cpp OrthancFramework/Sources/Enumerations.h OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp OrthancServer/Sources/ServerContext.cpp OrthancServer/Sources/main.cpp |
diffstat | 7 files changed, 41 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancFramework/Resources/CodeGeneration/ErrorCodes.json Fri Dec 08 10:27:24 2023 +0100 +++ b/OrthancFramework/Resources/CodeGeneration/ErrorCodes.json Tue Dec 12 17:20:10 2023 +0100 @@ -256,6 +256,12 @@ "Name": "ForbiddenAccess", "Description": "Access to a resource is forbidden" }, + { + "Code": 46, + "HttpStatus": 409, + "Name": "DuplicateResource", + "Description": "Duplicate resource" + },
--- a/OrthancFramework/Sources/Enumerations.cpp Fri Dec 08 10:27:24 2023 +0100 +++ b/OrthancFramework/Sources/Enumerations.cpp Tue Dec 12 17:20:10 2023 +0100 @@ -182,6 +182,9 @@ case ErrorCode_ForbiddenAccess: return "Access to a resource is forbidden"; + case ErrorCode_DuplicateResource: + return "Duplicate resource"; + case ErrorCode_SQLiteNotOpened: return "SQLite: The database is not opened"; @@ -2264,6 +2267,9 @@ case ErrorCode_ForbiddenAccess: return HttpStatus_403_Forbidden; + case ErrorCode_DuplicateResource: + return HttpStatus_409_Conflict; + case ErrorCode_CreateDicomNotString: return HttpStatus_400_BadRequest;
--- a/OrthancFramework/Sources/Enumerations.h Fri Dec 08 10:27:24 2023 +0100 +++ b/OrthancFramework/Sources/Enumerations.h Tue Dec 12 17:20:10 2023 +0100 @@ -170,6 +170,7 @@ ErrorCode_Revision = 43 /*!< A bad revision number was provided, which might indicate conflict between multiple writers */, ErrorCode_MainDicomTagsMultiplyDefined = 44 /*!< A main DICOM Tag has been defined multiple times for the same resource level */, ErrorCode_ForbiddenAccess = 45 /*!< Access to a resource is forbidden */, + ErrorCode_DuplicateResource = 46 /*!< Duplicate resource */, ErrorCode_SQLiteNotOpened = 1000 /*!< SQLite: The database is not opened */, ErrorCode_SQLiteAlreadyOpened = 1001 /*!< SQLite: Connection is already open */, ErrorCode_SQLiteCannotOpen = 1002 /*!< SQLite: Unable to open the database */,
--- a/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Fri Dec 08 10:27:24 2023 +0100 +++ b/OrthancServer/Plugins/Include/orthanc/OrthancCPlugin.h Tue Dec 12 17:20:10 2023 +0100 @@ -246,6 +246,7 @@ OrthancPluginErrorCode_Revision = 43 /*!< A bad revision number was provided, which might indicate conflict between multiple writers */, OrthancPluginErrorCode_MainDicomTagsMultiplyDefined = 44 /*!< A main DICOM Tag has been defined multiple times for the same resource level */, OrthancPluginErrorCode_ForbiddenAccess = 45 /*!< Access to a resource is forbidden */, + OrthancPluginErrorCode_DuplicateResource = 46 /*!< Duplicate resource */, OrthancPluginErrorCode_SQLiteNotOpened = 1000 /*!< SQLite: The database is not opened */, OrthancPluginErrorCode_SQLiteAlreadyOpened = 1001 /*!< SQLite: Connection is already open */, OrthancPluginErrorCode_SQLiteCannotOpen = 1002 /*!< SQLite: Unable to open the database */,
--- a/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp Fri Dec 08 10:27:24 2023 +0100 +++ b/OrthancServer/Sources/Database/StatelessDatabaseOperations.cpp Tue Dec 12 17:20:10 2023 +0100 @@ -3157,7 +3157,9 @@ // in very rare occasions in READ COMMITTED mode when multiple clients are pushing the same instance at the same time, // this thread will not create the instance because another thread has created it in the meantime. // At the end, there is always a thread that creates the instance and this is what we expect. - throw OrthancException(ErrorCode_InternalError, HttpStatus_409_Conflict, "No new instance while overwriting; this might happen if another client has pushed the same instance at the same time."); + + // Note, we must delete the attachments that have already been stored from this failed insertion (they have not yet been added into the DB) + throw OrthancException(ErrorCode_DuplicateResource, "No new instance while overwriting; this might happen if another client has pushed the same instance at the same time."); } } else
--- a/OrthancServer/Sources/ServerContext.cpp Fri Dec 08 10:27:24 2023 +0100 +++ b/OrthancServer/Sources/ServerContext.cpp Tue Dec 12 17:20:10 2023 +0100 @@ -710,9 +710,29 @@ typedef std::map<MetadataType, std::string> InstanceMetadata; InstanceMetadata instanceMetadata; - result.SetStatus(index_.Store( - instanceMetadata, summary, attachments, dicom.GetMetadata(), dicom.GetOrigin(), overwrite, - hasTransferSyntax, transferSyntax, hasPixelDataOffset, pixelDataOffset, pixelDataVR, isReconstruct)); + + try + { + result.SetStatus(index_.Store( + instanceMetadata, summary, attachments, dicom.GetMetadata(), dicom.GetOrigin(), overwrite, + hasTransferSyntax, transferSyntax, hasPixelDataOffset, pixelDataOffset, pixelDataVR, isReconstruct)); + } + catch (OrthancException& ex) + { + if (ex.GetErrorCode() == ErrorCode_DuplicateResource) + { + LOG(WARNING) << "Duplicate instance, deleting the attachments"; + + accessor.Remove(dicomInfo); + + if (dicomUntilPixelData.IsValid()) + { + accessor.Remove(dicomUntilPixelData); + } + + throw; + } + } // Only keep the metadata for the "instance" level dicom.ClearMetadata();
--- a/OrthancServer/Sources/main.cpp Fri Dec 08 10:27:24 2023 +0100 +++ b/OrthancServer/Sources/main.cpp Tue Dec 12 17:20:10 2023 +0100 @@ -820,6 +820,7 @@ PrintErrorCode(ErrorCode_Revision, "A bad revision number was provided, which might indicate conflict between multiple writers"); PrintErrorCode(ErrorCode_MainDicomTagsMultiplyDefined, "A main DICOM Tag has been defined multiple times for the same resource level"); PrintErrorCode(ErrorCode_ForbiddenAccess, "Access to a resource is forbidden"); + PrintErrorCode(ErrorCode_DuplicateResource, "Duplicate resource"); PrintErrorCode(ErrorCode_SQLiteNotOpened, "SQLite: The database is not opened"); PrintErrorCode(ErrorCode_SQLiteAlreadyOpened, "SQLite: Connection is already open"); PrintErrorCode(ErrorCode_SQLiteCannotOpen, "SQLite: Unable to open the database");