added resourceId for deferredBinaryTarget to avoid adding binary applications multiple times in one transaction

This commit is contained in:
Kateryna Mironova 2023-11-07 18:51:15 -05:00
parent 3062fad839
commit 2a8ef9ac1d
3 changed files with 58 additions and 8 deletions

View File

@ -0,0 +1,5 @@
---
type: fix
issue: 5437
jira: SMILE-7588
title: "Previously, when adding several binary resources in one bundle in a transaction, the EntityExistsException error appeared. This is now fixed."

View File

@ -558,4 +558,40 @@ public class BinaryStorageInterceptorR4Test extends BaseResourceProviderR4Test {
content.getAttachment().setData(theData);
}
@Test
public void testCreateBundleWithMultipleBinaryAttachments_createdSuccessfully() {
Binary binary = new Binary();
binary.setContentType("application/octet-stream");
binary.setData(SOME_BYTES);
DocumentReference docRef = new DocumentReference();
addDocumentAttachmentData(docRef, SOME_BYTES_2);
// Prepare the bundle
Bundle bundle = new Bundle();
bundle.setType(Bundle.BundleType.TRANSACTION);
addBundleEntry(bundle, binary, "Binary");
addBundleEntry(bundle, docRef, "DocumentReference");
// Execute transaction
Bundle output = myClient.transaction().withBundle(bundle).execute();
ourLog.debug(myFhirContext.newXmlParser().setPrettyPrint(true).encodeResourceToString(output));
// Verify bundle response
assertEquals(2, output.getEntry().size());
output.getEntry().forEach(entry -> assertEquals("201 Created", entry.getResponse().getStatus()));
// Verify Binary and attachment
IIdType binaryId = new IdType(output.getEntry().get(0).getResponse().getLocation());
Binary actualBinary = myBinaryDao.read(binaryId, mySrd);
assertEquals(binary.getContentType(), actualBinary.getContentType());
assertArrayEquals(SOME_BYTES, actualBinary.getData());
// Verify DocumentReference and attachments
IIdType docRefId = new IdType(output.getEntry().get(1).getResponse().getLocation());
DocumentReference actualDocRef = myDocumentReferenceDao.read(docRefId, mySrd);
assertEquals("application/octet-stream", actualDocRef.getContentFirstRep().getAttachment().getContentType());
assertArrayEquals(SOME_BYTES_2, actualDocRef.getContentFirstRep().getAttachment().getData());
}
}

View File

@ -253,7 +253,7 @@ public class BinaryStorageInterceptor<T extends IPrimitiveType<byte[]>> {
List<DeferredBinaryTarget> deferredBinaryTargets =
getOrCreateDeferredBinaryStorageList(theResource);
DeferredBinaryTarget newDeferredBinaryTarget =
new DeferredBinaryTarget(newBlobId, nextTarget, data);
new DeferredBinaryTarget(newBlobId, resourceId.getValue(), nextTarget, data);
deferredBinaryTargets.add(newDeferredBinaryTarget);
newDeferredBinaryTarget.setBlobIdPrefixHookApplied(true);
} else {
@ -312,12 +312,14 @@ public class BinaryStorageInterceptor<T extends IPrimitiveType<byte[]>> {
if (deferredBinaryTargetList != null) {
IIdType resourceId = theResource.getIdElement();
for (DeferredBinaryTarget next : (List<DeferredBinaryTarget>) deferredBinaryTargetList) {
String blobId = next.getBlobId();
IBinaryTarget target = next.getBinaryTarget();
InputStream dataStream = next.getDataStream();
String contentType = target.getContentType();
RequestDetails requestDetails = initRequestDetails(next);
myBinaryStorageSvc.storeBlob(resourceId, blobId, contentType, dataStream, requestDetails);
if (resourceId.getValueAsString().equals(next.getResourceId())) {
String blobId = next.getBlobId();
IBinaryTarget target = next.getBinaryTarget();
InputStream dataStream = next.getDataStream();
String contentType = target.getContentType();
RequestDetails requestDetails = initRequestDetails(next);
myBinaryStorageSvc.storeBlob(resourceId, blobId, contentType, dataStream, requestDetails);
}
}
}
}
@ -422,12 +424,15 @@ public class BinaryStorageInterceptor<T extends IPrimitiveType<byte[]>> {
private static class DeferredBinaryTarget {
private final String myBlobId;
private final String myResourceId;
private final IBinaryTarget myBinaryTarget;
private final InputStream myDataStream;
private boolean myBlobIdPrefixHookApplied;
private DeferredBinaryTarget(String theBlobId, IBinaryTarget theBinaryTarget, byte[] theData) {
private DeferredBinaryTarget(
String theBlobId, String theResourceId, IBinaryTarget theBinaryTarget, byte[] theData) {
myBlobId = theBlobId;
myResourceId = theResourceId;
myBinaryTarget = theBinaryTarget;
myDataStream = new ByteArrayInputStream(theData);
}
@ -436,6 +441,10 @@ public class BinaryStorageInterceptor<T extends IPrimitiveType<byte[]>> {
return myBlobId;
}
String getResourceId() {
return myResourceId;
}
IBinaryTarget getBinaryTarget() {
return myBinaryTarget;
}