|
23 | 23 | import bio.overture.score.core.model.ObjectKey; |
24 | 24 | import bio.overture.score.core.model.ObjectSpecification; |
25 | 25 | import bio.overture.score.core.model.Part; |
| 26 | +import bio.overture.score.core.util.MD5s; |
26 | 27 | import bio.overture.score.core.util.ObjectKeys; |
27 | 28 | import bio.overture.score.core.util.PartCalculator; |
| 29 | +import bio.overture.score.server.config.S3Config; |
28 | 30 | import bio.overture.score.server.exception.IdNotFoundException; |
29 | 31 | import bio.overture.score.server.exception.InternalUnrecoverableError; |
30 | 32 | import bio.overture.score.server.exception.NotRetryableException; |
@@ -89,6 +91,7 @@ public class S3DownloadService implements DownloadService { |
89 | 91 | @Autowired private URLGenerator urlGenerator; |
90 | 92 | @Autowired private PartCalculator partCalculator; |
91 | 93 | @Autowired private MetadataService metadataService; |
| 94 | + @Autowired private S3Config s3config; |
92 | 95 |
|
93 | 96 | @Override |
94 | 97 | public ObjectSpecification download( |
@@ -118,14 +121,17 @@ public ObjectSpecification download( |
118 | 121 | parts = partCalculator.divide(offset, length); |
119 | 122 | } |
120 | 123 | fillPartUrls(objectKey, parts, false, forExternalUse); |
| 124 | + |
| 125 | + val md5 = getObjectMd5(metadata); |
| 126 | + |
121 | 127 | objectSpec = |
122 | 128 | new ObjectSpecification( |
123 | 129 | objectKey.getKey(), |
124 | 130 | objectId, |
125 | 131 | objectId, |
126 | 132 | parts, |
127 | 133 | metadata.getContentLength(), |
128 | | - metadata.getETag(), |
| 134 | + md5, |
129 | 135 | false); |
130 | 136 | } |
131 | 137 |
|
@@ -189,6 +195,35 @@ public ObjectSpecification download( |
189 | 195 | } |
190 | 196 | } |
191 | 197 |
|
| 198 | + /** |
| 199 | + * Looks for MD5 hash in the object metadata. This is used as part of the fallback behaviour when |
| 200 | + * the .meta file cannot be found. To find the MD5, we will look for a value using the built in S3 |
| 201 | + * getContendMD5(), and if no value is found there we will check in a configurable user meta data |
| 202 | + * property. The name of this property is configurable via the S3 Config. If no MD5 value can be |
| 203 | + * found in either of these locations then it will be returned null. |
| 204 | + * |
| 205 | + * <p>A user can still download files with the MD5 set to null, but they will always fail to |
| 206 | + * validate through the CLI. To complete a download of a file in this state, the user should add |
| 207 | + * the argument to their CLI download command: --validate false |
| 208 | + * |
| 209 | + * @param metadata |
| 210 | + * @return |
| 211 | + */ |
| 212 | + private String getObjectMd5(ObjectMetadata metadata) { |
| 213 | + val contentMd5 = metadata.getContentMD5(); |
| 214 | + if (contentMd5 != null) { |
| 215 | + return MD5s.toHex(contentMd5); |
| 216 | + } |
| 217 | + val userMetadataMd5 = |
| 218 | + metadata.getUserMetaDataOf(s3config.getCustomMd5Property()); // get literal from config |
| 219 | + if (userMetadataMd5 != null) { |
| 220 | + return MD5s.toHex(userMetadataMd5); |
| 221 | + } |
| 222 | + |
| 223 | + // No value found, returning null. |
| 224 | + return null; |
| 225 | + } |
| 226 | + |
192 | 227 | private static ObjectSpecification removeUrls(ObjectSpecification spec) { |
193 | 228 | spec.getParts().forEach(x -> x.setUrl(null)); |
194 | 229 | return spec; |
|
0 commit comments