Add fix
This commit is contained in:
parent
0f58641030
commit
5bfc5f02f6
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
Loading…
Reference in New Issue