This commit is contained in:
Tadgh 2024-07-19 12:52:20 -07:00
parent 0f58641030
commit 5bfc5f02f6
4 changed files with 65 additions and 6 deletions

View File

@ -0,0 +1,36 @@
package ca.uhn.fhir.jpa.binary.api;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import java.io.IOException;
/**
* This deserializer exists to fix a break that changing this property name caused.
* in 7.2.0 we went from blobId to binaryContentId. However this did not consider installations using filesystem
* mode storage in which the data on disk was not updated, and existing stored details used `blobId`. This causes
* Jackson deserialization failures which are tough to recover from without manually modifying all those stored details
* on disk.
* <p>
* <p>
* This class is a shim to support the old and new names.
*/
class BinaryContentIdDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JacksonException {
JsonNode node = jp.getCodec().readTree(jp);
JsonNode binaryContentIdNode = node.get("binaryContentId");
if (binaryContentIdNode != null && !binaryContentIdNode.isNull()) {
return binaryContentIdNode.asText();
}
JsonNode blobIdNode = node.get("blobId");
if (blobIdNode != null && !blobIdNode.isNull()) {
return blobIdNode.asText();
}
return null;
}
}

View File

@ -137,9 +137,13 @@ public class OldStoredDetails implements IModelJson {
public StoredDetails toDetails() { public StoredDetails toDetails() {
HashFunction hash = Hashing.sha256(); HashFunction hash = Hashing.sha256();
StoredDetails storedDetails = new StoredDetails(myBinaryContentId, myBytes, myContentType, new HashingInputStream(hash,new ByteArrayInputStream("whatever".getBytes())), myPublished); StoredDetails storedDetails = new StoredDetails(
myBinaryContentId,
myBytes,
myContentType,
new HashingInputStream(hash, new ByteArrayInputStream("whatever".getBytes())),
myPublished);
storedDetails.setHash(myHash); storedDetails.setHash(myHash);
return storedDetails; return storedDetails;
} }
} }

View File

@ -33,9 +33,22 @@ import java.util.Date;
public class StoredDetails implements IModelJson { public class StoredDetails implements IModelJson {
@JsonProperty("binaryContentId") @JsonProperty(value = "binaryContentId")
private String myBinaryContentId; private String myBinaryContentId;
/**
* This field exists to fix a break that changing this property name caused.
* in 7.2.0 we went from blobId to binaryContentId. However this did not consider installations using filesystem
* mode storage in which the data on disk was not updated, and needed to be Serialized/Deserialized at runtime.
* Existing stored details used `blobId`. This causes Jackson deserialization failures which are tough to recover
* from without manually modifying all those stored details
* on disk.
* This field is a relic to support old blobs post-upgrade to 7.2.0. It is not ever surfaced to the user, and is proxied
* into `myBinaryContentId` when needed.
*/
@JsonProperty(value = "blobId")
private String myBlobId;
@JsonProperty("bytes") @JsonProperty("bytes")
private long myBytes; private long myBytes;
@ -77,7 +90,7 @@ public class StoredDetails implements IModelJson {
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this) return new ToStringBuilder(this)
.append("binaryContentId", myBinaryContentId) .append("binaryContentId", getBinaryContentId())
.append("bytes", myBytes) .append("bytes", myBytes)
.append("contentType", myContentType) .append("contentType", myContentType)
.append("hash", myHash) .append("hash", myHash)
@ -115,7 +128,11 @@ public class StoredDetails implements IModelJson {
@Nonnull @Nonnull
public String getBinaryContentId() { public String getBinaryContentId() {
return myBinaryContentId; if (myBinaryContentId == null && myBlobId != null) {
return myBlobId;
} else {
return myBinaryContentId;
}
} }
public StoredDetails setBinaryContentId(String theBinaryContentId) { public StoredDetails setBinaryContentId(String theBinaryContentId) {
@ -131,4 +148,5 @@ public class StoredDetails implements IModelJson {
myBytes = theBytes; myBytes = theBytes;
return this; return this;
} }
} }

View File

@ -113,7 +113,8 @@ public class FilesystemBinaryStorageSvcImpl extends BaseBinaryStorageSvcImpl {
long count = countingInputStream.getByteCount(); long count = countingInputStream.getByteCount();
StoredDetails details = null; StoredDetails details = null;
if (HapiSystemProperties.isUnitTestModeEnabled()) { if (HapiSystemProperties.isUnitTestModeEnabled()) {
OldStoredDetails oldDetails = new OldStoredDetails(id, count, theContentType, hashingInputStream, new Date()); OldStoredDetails oldDetails =
new OldStoredDetails(id, count, theContentType, hashingInputStream, new Date());
File descriptorFilename = getDescriptorFilename(storagePath, theResourceId, id); File descriptorFilename = getDescriptorFilename(storagePath, theResourceId, id);
ourLog.info("Writing to file: {}", descriptorFilename.getAbsolutePath()); ourLog.info("Writing to file: {}", descriptorFilename.getAbsolutePath());
try (FileWriter writer = new FileWriter(descriptorFilename)) { try (FileWriter writer = new FileWriter(descriptorFilename)) {