Skip to content

Commit

Permalink
feat($oss-center): add new API for resource response
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnymillergh committed Sep 3, 2021
1 parent f8f88c4 commit 29b3e75
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,15 @@
public class ReadResourceController {
private final ReadResourceService readResourceService;

@GetMapping("/{bucket}/{object}")
@ApiOperation(value = "Get single resource", notes = "Get single resource (small-size file)")
public ResponseEntity<StreamingResponseBody> asyncGetSingleResource(@PathVariable String bucket,
@PathVariable String object) {
return this.readResourceService.asyncGetSingleResource(bucket, object);
}

@GetMapping("/stream/{bucket}/{object}")
@ApiOperation(value = "Stream single resource", notes = "Stream single resource")
@ApiOperation(value = "Stream single resource", notes = "Stream single resource (large-size file)")
public ResponseEntity<StreamingResponseBody> asyncStreamSingleResource(@PathVariable String bucket,
@PathVariable String object,
@RequestHeader(name = HttpHeaders.RANGE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,17 @@ public interface ReadResourceService {
DataSize LARGE_CHUNK_SIZE = DataSize.ofMegabytes(8);

/**
* Async stream single resource response entity.
* Get single resource, especially pictures, or other small size file.
*
* @param bucket the bucket
* @param object the object
* @return the response entity
*/
ResponseEntity<StreamingResponseBody> asyncGetSingleResource(String bucket, String object);

/**
* Stream single resource, more efficiency if the resource is large file, which will be streamed by range.
* Responsive streaming
*
* @param bucket the bucket
* @param object the object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,32 @@
@Service
@RequiredArgsConstructor
public class ReadResourceServiceImpl implements ReadResourceService {
private static final String ACCEPT_RANGES_VALUE = "bytes";
private final MinioHelper minioHelper;

@Override
@SuppressWarnings("DuplicatedCode")
public ResponseEntity<StreamingResponseBody> asyncGetSingleResource(String bucket, String object) {
StatObjectResponse statObjectResponse;
try {
statObjectResponse = this.minioHelper.statObject(bucket, object);
} catch (Exception e) {
log.error("Exception occurred when looking for object. Exception message: {}", e.getMessage());
return ResponseEntity.notFound().build();
}
val getObjectResponse = this.minioHelper.getObject(bucket, object);
return ResponseEntity.ok()
.header(HttpHeaders.ACCEPT_RANGES, ACCEPT_RANGES_VALUE)
.contentLength(statObjectResponse.size())
.contentType(MediaType.parseMediaType(statObjectResponse.contentType()))
.body(outputStream -> {
NioUtil.copyByNIO(getObjectResponse, outputStream, NioUtil.DEFAULT_BUFFER_SIZE, null);
IoUtil.close(getObjectResponse);
});
}

@Override
@SuppressWarnings("DuplicatedCode")
public ResponseEntity<StreamingResponseBody> asyncStreamSingleResource(@NotBlank String bucket,
@NotBlank String object,
@Nullable String range) {
Expand All @@ -46,7 +69,7 @@ public ResponseEntity<StreamingResponseBody> asyncStreamSingleResource(@NotBlank
if (CollUtil.isEmpty(httpRanges)) {
val getObjectResponse = this.minioHelper.getObject(bucket, object, 0, TINY_CHUNK_SIZE.toBytes());
return ResponseEntity.ok()
.header(HttpHeaders.ACCEPT_RANGES, "bytes")
.header(HttpHeaders.ACCEPT_RANGES, ACCEPT_RANGES_VALUE)
.contentLength(statObjectResponse.size())
.contentType(MediaType.parseMediaType(statObjectResponse.contentType()))
.body(outputStream -> {
Expand All @@ -70,7 +93,7 @@ public ResponseEntity<StreamingResponseBody> asyncDownloadSingleResource(@NotBla
}
val getObjectResponse = this.minioHelper.getObject(bucket, object);
return ResponseEntity.ok()
.header(HttpHeaders.ACCEPT_RANGES, "bytes")
.header(HttpHeaders.ACCEPT_RANGES, ACCEPT_RANGES_VALUE)
.header(HttpHeaders.CONTENT_DISPOSITION,
ContentDisposition.builder("attachment").filename(object).build().toString())
.contentLength(statObjectResponse.size())
Expand Down Expand Up @@ -98,7 +121,7 @@ private ResponseEntity<StreamingResponseBody> asyncGetResourceRegion(String buck
end = Math.min(end, resourceLength - 1);
val rangeLength = end - start + 1;
return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT)
.header(HttpHeaders.ACCEPT_RANGES, "bytes")
.header(HttpHeaders.ACCEPT_RANGES, ACCEPT_RANGES_VALUE)
.header(HttpHeaders.CONTENT_RANGE, String.format("bytes %d-%d/%d", start, end, resourceLength))
.contentLength(rangeLength)
.contentType(MediaType.parseMediaType(statObjectResponse.contentType()))
Expand Down

0 comments on commit 29b3e75

Please sign in to comment.