diff --git a/bulkupload/build.gradle b/bulkupload/build.gradle index de8ef60a..0ce5e4d5 100644 --- a/bulkupload/build.gradle +++ b/bulkupload/build.gradle @@ -5,7 +5,7 @@ plugins { } group = 'com.example' -version = '0.0.1-SNAPSHOT' +version = '1.0' sourceCompatibility = '11' configurations { diff --git a/bulkupload/src/main/java/com/example/bulkupload/config/TusConfig.java b/bulkupload/src/main/java/com/example/bulkupload/config/TusConfig.java index 84fc0f09..4faf3816 100644 --- a/bulkupload/src/main/java/com/example/bulkupload/config/TusConfig.java +++ b/bulkupload/src/main/java/com/example/bulkupload/config/TusConfig.java @@ -29,7 +29,7 @@ public class TusConfig { .withStoragePath(tusStoragePath) .withDownloadFeature() .withUploadExpirationPeriod(tusExpirationPeriod) - .withUploadURI("/api/tus/file/upload"); + .withUploadURI("/api/upload"); } } diff --git a/bulkupload/src/main/java/com/example/bulkupload/config/WebConfig.java b/bulkupload/src/main/java/com/example/bulkupload/config/WebConfig.java index 06801ded..428fca76 100644 --- a/bulkupload/src/main/java/com/example/bulkupload/config/WebConfig.java +++ b/bulkupload/src/main/java/com/example/bulkupload/config/WebConfig.java @@ -2,6 +2,7 @@ package com.example.bulkupload.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration diff --git a/bulkupload/src/main/java/com/example/bulkupload/controller/TusUploadController.java b/bulkupload/src/main/java/com/example/bulkupload/controller/TusUploadController.java index 8f14f76f..5d633481 100644 --- a/bulkupload/src/main/java/com/example/bulkupload/controller/TusUploadController.java +++ b/bulkupload/src/main/java/com/example/bulkupload/controller/TusUploadController.java @@ -3,39 +3,75 @@ package com.example.bulkupload.controller; import com.example.bulkupload.service.FileUploadService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.CrossOrigin; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.Resource; +import org.springframework.core.io.support.ResourceRegion; +import org.springframework.http.*; +import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.concurrent.TimeUnit; @Slf4j @RestController @RequiredArgsConstructor +@RequestMapping("/api") public class TusUploadController { private final FileUploadService fileUploadService; - @CrossOrigin(origins = "*") - @RequestMapping(value = {"/api/tus/file/upload", "/api/tus/file/upload/**"}) - public ResponseEntity uploadWithTus(HttpServletRequest request, HttpServletResponse response) { - // Process a tus upload request - fileUploadService.process(request, response); + @Value("${video.path}") + private String savedPath; - // Generate HTTP Response Headers - return httpOkStatus(); + @CrossOrigin(origins = "*") + @RequestMapping(value = {"/upload", "/upload/**"}) + public ResponseEntity uploadWithTus2(HttpServletRequest request, HttpServletResponse response) { + String filename = fileUploadService.process(request, response); + return httpOkStatus(filename); } - private static ResponseEntity httpOkStatus() { + private static ResponseEntity httpOkStatus(String filename) { HttpHeaders headers = new HttpHeaders(); headers.set(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*"); return ResponseEntity.status(HttpStatus.OK) .headers(headers) - .build(); + .body(filename); } + + @GetMapping("/video/{date}/{url}") + public ResponseEntity videoResource(@RequestHeader HttpHeaders headers, + @PathVariable String date, + @PathVariable String url) throws IOException { + String path = savedPath + "/" + date + "/" + url; + Resource resource = new FileSystemResource(path); + + long chunkSize = 1024 * 1024; + long contentLength = resource.contentLength(); + + ResourceRegion region; + + try { + HttpRange httpRange = headers.getRange().stream().findFirst().get(); + long start = httpRange.getRangeStart(contentLength); + long end = httpRange.getRangeEnd(contentLength); + long rangeLength = Long.min(chunkSize, end -start + 1); + + region = new ResourceRegion(resource, start, rangeLength); + } catch (Exception e) { + long rangeLength = Long.min(chunkSize, contentLength); + region = new ResourceRegion(resource, 0, rangeLength); + } + + return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT) + .cacheControl(CacheControl.maxAge(10, TimeUnit.MINUTES)) + .contentType(MediaTypeFactory.getMediaType(resource).orElse(MediaType.APPLICATION_OCTET_STREAM)) + .header("Accept-Ranges", "bytes") + .eTag(path) + .body(region); + } + } \ No newline at end of file diff --git a/bulkupload/src/main/java/com/example/bulkupload/service/FileUploadService.java b/bulkupload/src/main/java/com/example/bulkupload/service/FileUploadService.java index a81636f8..99ea43f4 100644 --- a/bulkupload/src/main/java/com/example/bulkupload/service/FileUploadService.java +++ b/bulkupload/src/main/java/com/example/bulkupload/service/FileUploadService.java @@ -6,6 +6,7 @@ import me.desair.tus.server.TusFileUploadService; import me.desair.tus.server.exception.TusException; import me.desair.tus.server.upload.UploadInfo; import org.apache.commons.io.FileUtils; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; @@ -13,6 +14,8 @@ import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.time.LocalDate; +import java.util.UUID; @Slf4j @Service @@ -21,21 +24,24 @@ public class FileUploadService { private final TusFileUploadService tusFileUploadService; - public void process(HttpServletRequest request, HttpServletResponse response) { + @Value("${video.path}") + private String savedPath; + + public String process(HttpServletRequest request, HttpServletResponse response) { try { - // Process a tus upload request tusFileUploadService.process(request, response); - // Get upload information UploadInfo uploadInfo = tusFileUploadService.getUploadInfo(request.getRequestURI()); if (uploadInfo != null && !uploadInfo.isUploadInProgress()) { - // Progress status is successful: Create file - createFile(tusFileUploadService.getUploadedBytes(request.getRequestURI()), uploadInfo.getFileName()); + String filename = createFile(tusFileUploadService.getUploadedBytes(request.getRequestURI()), uploadInfo.getFileName()); - // Delete an upload associated with the given upload url tusFileUploadService.deleteUpload(request.getRequestURI()); + + return filename; } + + return null; } catch (IOException | TusException e) { log.error("exception was occurred. message={}", e.getMessage(), e); @@ -43,9 +49,18 @@ public class FileUploadService { } } - private void createFile(InputStream is, String filename) throws IOException { - File file = new File("dest/", filename); + private String createFile(InputStream is, String filename) throws IOException { + String uuid = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 12); + + String[] split = filename.split("\\."); + + String savedFilename = uuid + "." + split[split.length - 1]; + + LocalDate today = LocalDate.now(); + File file = new File(savedPath + "/" + today, savedFilename); FileUtils.copyInputStreamToFile(is, file); + + return today + "/" + savedFilename; } } \ No newline at end of file diff --git a/bulkupload/src/main/resources/application-dev.yml b/bulkupload/src/main/resources/application-dev.yml new file mode 100644 index 00000000..8bda0954 --- /dev/null +++ b/bulkupload/src/main/resources/application-dev.yml @@ -0,0 +1,8 @@ +tus: + server: + data: + directory: "/data/tus" + expiration: 86400000 + +video: + path: /data/video diff --git a/bulkupload/src/main/resources/application.yml b/bulkupload/src/main/resources/application.yml index 00c6be58..f8ac2384 100644 --- a/bulkupload/src/main/resources/application.yml +++ b/bulkupload/src/main/resources/application.yml @@ -1,9 +1,15 @@ +server: + port: 18081 + tus: server: data: directory: "/Users/bobby/Downloads/tus" expiration: 86400000 +video: + path: "/Users/bobby/Downloads/tus/video" + spring: servlet: multipart: diff --git a/bulkupload/src/main/resources/templates/index.html b/bulkupload/src/main/resources/templates/index.html index 769a233c..eb7013bd 100644 --- a/bulkupload/src/main/resources/templates/index.html +++ b/bulkupload/src/main/resources/templates/index.html @@ -93,8 +93,7 @@ ` let upload = new tus.Upload(file, { - // endpoint : 'https://tusd.tusdemo.net/files/', - endpoint: "http://169.254.130.102:8080/api/tus/file/upload", + endpoint: "/api/upload", chunkSize, retryDelays: [0, 1000, 3000, 5000], metadata: {