Skip to content

Commit 216edc9

Browse files
Azher2AliAzherAliMohammedjoneubank
authored
Generate Logical Parts for object downloads when no .meta file is available (#413)
* Refactor S3 Bucket Name Retrieval Method * Object Retrieval: Support for Multipart Uploads * Used getContentLength() from the ObjectMetaData to Calculate the part * Update Part.java Reverting changes related to Part.java * Handle case where external=false and length < 0 --------- Co-authored-by: AzherAliMohammed <68929005+AzherAliMohammed@users.noreply.github.com> Co-authored-by: Jon Eubank <joneubank@gmail.com>
1 parent 13a8534 commit 216edc9

1 file changed

Lines changed: 60 additions & 42 deletions

File tree

score-server/src/main/java/bio/overture/score/server/repository/s3/S3DownloadService.java

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -97,65 +97,82 @@ public ObjectSpecification download(
9797
if (!excludeUrls) {
9898
checkPublishedAnalysisState(metadataService.getEntity(objectId));
9999
}
100-
101100
checkArgument(offset > -1L);
102101

103-
var objectSpec = getSpecification(objectId);
104-
105-
// Construct ObjectSpecification for actual object in /data logical folder
106102
val objectKey = ObjectKeys.getObjectKey(dataDir, objectId);
107103

108-
List<Part> parts;
109-
if (forExternalUse) {
110-
// Return as a single part - no matter how large
111-
parts = partCalculator.specify(0L, -1L);
112-
} else {
113-
parts = partCalculator.divide(offset, length);
114-
}
104+
var objectSpec = getSpecification(objectId);
105+
115106
if (objectSpec == null) {
116107
ObjectMetadata metadata =
117108
s3Client.getObjectMetadata(
118109
bucketNamingService.getObjectBucketName(objectId), objectKey.getKey());
110+
111+
List<Part> parts;
112+
if (forExternalUse) {
113+
// Return as a single part - no matter how large
114+
parts = partCalculator.specify(0L, -1L);
115+
} else if (length < 0L) {
116+
parts = partCalculator.divide(offset, metadata.getContentLength() - offset);
117+
} else {
118+
parts = partCalculator.divide(offset, length);
119+
}
119120
fillPartUrls(objectKey, parts, false, forExternalUse);
120121
objectSpec =
121122
new ObjectSpecification(
122-
objectKey.getKey(), objectId, objectId, parts, metadata.getContentLength(), metadata.getETag(), false);
123+
objectKey.getKey(),
124+
objectId,
125+
objectId,
126+
parts,
127+
metadata.getContentLength(),
128+
metadata.getETag(),
129+
false);
123130
}
124131

125132
// Short-circuit in default case
126-
if (!forExternalUse && (offset == 0L && length < 0L)) {
127-
return excludeUrls ? removeUrls(objectSpec) : objectSpec;
128-
}
133+
if (!forExternalUse && (offset == 0L && length < 0L)) {
134+
return excludeUrls ? removeUrls(objectSpec) : objectSpec;
135+
}
129136

130-
// Calculate range values
131-
// To retrieve to the end of the file
132-
if (!forExternalUse && (length < 0L)) {
133-
length = objectSpec.getObjectSize() - offset;
134-
}
137+
// Construct ObjectSpecification for actual object in /data logical folder
138+
// Calculate range values
139+
// To retrieve to the end of the file
140+
if (!forExternalUse && (length < 0L)) {
141+
length = objectSpec.getObjectSize() - offset;
142+
}
135143

136-
// Validate offset and length parameters:
137-
// Check if the offset + length > length - that would be too big
138-
if ((offset + length) > objectSpec.getObjectSize()) {
139-
throw new InternalUnrecoverableError(
140-
"Specified parameters exceed object size (object id: "
141-
+ objectId
142-
+ ", offset: "
143-
+ offset
144-
+ ", length: "
145-
+ length
146-
+ ")");
147-
}
148-
fillPartUrls(objectKey, parts, objectSpec.isRelocated(), forExternalUse);
144+
// Validate offset and length parameters:
145+
// Check if the offset + length > length - that would be too big
146+
if ((offset + length) > objectSpec.getObjectSize()) {
147+
throw new InternalUnrecoverableError(
148+
"Specified parameters exceed object size (object id: "
149+
+ objectId
150+
+ ", offset: "
151+
+ offset
152+
+ ", length: "
153+
+ length
154+
+ ")");
155+
}
149156

150-
val spec =
151-
new ObjectSpecification(
152-
objectKey.getKey(),
153-
objectId,
154-
objectId,
155-
parts,
156-
length,
157-
objectSpec.getObjectMd5(),
158-
objectSpec.isRelocated());
157+
List<Part> parts;
158+
if (forExternalUse) {
159+
// Return as a single part - no matter how large
160+
parts = partCalculator.specify(0L, -1L);
161+
} else {
162+
parts = partCalculator.divide(offset, length);
163+
}
164+
165+
fillPartUrls(objectKey, parts, objectSpec.isRelocated(), forExternalUse);
166+
167+
val spec =
168+
new ObjectSpecification(
169+
objectKey.getKey(),
170+
objectId,
171+
objectId,
172+
parts,
173+
length,
174+
objectSpec.getObjectMd5(),
175+
objectSpec.isRelocated());
159176

160177
return excludeUrls ? removeUrls(spec) : spec;
161178
} catch (Exception e) {
@@ -193,6 +210,7 @@ void checkPublishedAnalysisState(MetadataEntity entity) {
193210
}
194211
}
195212
}
213+
196214
public ObjectSpecification getSpecification(String objectId) {
197215
val objectKey = ObjectKeys.getObjectKey(dataDir, objectId);
198216
val objectMetaKey = ObjectKeys.getObjectMetaKey(dataDir, objectId);

0 commit comments

Comments
 (0)