Commit d1afddb8 authored by Matija Obreza's avatar Matija Obreza

Repository Download controller added to API v1

parent eea1212b
......@@ -110,7 +110,7 @@ public class RepositoryController {
* @throws NoSuchRepositoryFileException the no such repository file exception
* @throws IOException Signals that an I/O exception has occurred.
*/
@GetMapping(value = "/download/{fileUuid}")
@GetMapping(value = "/download/{fileUuid:\\w{8}\\-\\w{4}.+}")
public void downloadFile(@PathVariable("fileUuid") final UUID fileUuid, final HttpServletResponse response) throws NoSuchRepositoryFileException, IOException {
final RepositoryFile repositoryFile = repositoryService.getFile(fileUuid);
......
......@@ -152,7 +152,7 @@ public class RepositoryController {
* @throws NoSuchRepositoryFileException the no such repository file exception
* @throws IOException Signals that an I/O exception has occurred.
*/
@GetMapping(value = "/download/{fileUuid}")
@GetMapping(value = "/download/{fileUuid:\\w{8}\\-\\w{4}.+}")
public void downloadFile(@PathVariable("fileUuid") final UUID fileUuid, final HttpServletResponse response) throws NoSuchRepositoryFileException, IOException {
final RepositoryFile repositoryFile = repositoryService.getFile(fileUuid);
......
/*
* Copyright 2017 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.genesys2.server.api.v1;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.genesys.filerepository.NoSuchRepositoryFileException;
import org.genesys.filerepository.model.RepositoryFile;
import org.genesys.filerepository.service.BytesStorageService;
import org.genesys.filerepository.service.ImageGalleryService;
import org.genesys.filerepository.service.RepositoryService;
import org.genesys2.spring.ResourceNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.HandlerMapping;
/**
* This controller servers thumbnails and files.
*
* @author Matija Obreza
*/
@Controller("repositoryDownload1")
public class RepositoryDownloadController {
public static final Logger LOG = LoggerFactory.getLogger(RepositoryDownloadController.class);
@Autowired
private RepositoryService repositoryService;
@Autowired
private BytesStorageService byteStorageService;
private void downloadFile(final String path, final String uuid, final String ext, final HttpServletResponse response) throws IOException {
byte[] data;
if (path.startsWith(ImageGalleryService.THUMB_PATH) && ext.equals(ImageGalleryService.THUMB_EXT)) {
final String filename = uuid + ext;
if (LOG.isDebugEnabled()) {
LOG.debug("_thumb path={} filename={}", path, filename);
}
data = this.byteStorageService.get(Paths.get(path, filename));
response.setContentType("image/png");
} else {
// Regular repo file
try {
final RepositoryFile repositoryFile = this.repositoryService.getFile(UUID.fromString(uuid));
sanityCheck(Paths.get(path), ext, repositoryFile);
data = this.repositoryService.getFileBytes(repositoryFile);
response.setHeader(HttpHeaders.CACHE_CONTROL, "max-age=86400, s-maxage=86400, public, no-transform");
response.setHeader(HttpHeaders.PRAGMA, "");
response.setDateHeader(HttpHeaders.LAST_MODIFIED, repositoryFile.getLastModifiedDate().getTime());
response.setContentType(repositoryFile.getContentType());
response.addHeader("Content-Disposition", String.format("attachment; filename=\"%s\"", repositoryFile.getOriginalFilename()));
} catch (final NumberFormatException e) {
LOG.warn("404 - UUID in wrong format.");
throw new ResourceNotFoundException("No such thing", e);
} catch (final NoSuchRepositoryFileException e) {
LOG.warn("404 - No such repository file ", e);
throw new ResourceNotFoundException("No such thing", e);
}
}
if (data != null) {
response.setContentLength(data.length);
response.getOutputStream().write(data);
}
response.flushBuffer();
}
private void sanityCheck(final Path path, final String ext, final RepositoryFile repositoryFile) {
if (repositoryFile == null) {
throw new ResourceNotFoundException("No such thing");
}
if (!repositoryFile.getStorageFolder().equals(path.toString()) || !repositoryFile.getExtension().equals(ext)) {
LOG.warn("{}!={}", repositoryFile.getStorageFolder(), path);
LOG.warn("{}!={}", repositoryFile.getExtension(), ext);
throw new ResourceNotFoundException("No such thing");
}
}
/**
* Serve the bytes of the repository object
*/
@RequestMapping(value = RepositoryController.CONTROLLER_URL + "/download/d/**", method = RequestMethod.GET)
public void downloadFile(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
final String fullpath = ((String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)).substring((RepositoryController.CONTROLLER_URL + "/download/d").length());
if (LOG.isTraceEnabled()) {
LOG.trace("Fullname: {}", fullpath);
}
final String ext = fullpath.substring(fullpath.lastIndexOf("."));
final String uuid = fullpath.substring(fullpath.lastIndexOf("/") + 1, fullpath.lastIndexOf("."));
final String path = fullpath.substring(0, fullpath.lastIndexOf('/'));
if (LOG.isDebugEnabled()) {
LOG.debug("{} {}", path, uuid + ext);
}
downloadFile(path, uuid, ext, response);
}
/**
* Return repository object metadata
*/
@RequestMapping(value = RepositoryController.CONTROLLER_URL + "/download/d/**", method = RequestMethod.GET, params = { "metadata" }, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody RepositoryFile getMetadata(final HttpServletRequest request) throws IOException, NoSuchRepositoryFileException {
final String fullpath = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
LOG.debug("Fullname: {}", fullpath);
String path;
String uuid;
String ext;
try {
ext = fullpath.substring(fullpath.lastIndexOf("."));
uuid = fullpath.substring(fullpath.lastIndexOf("/") + 1, fullpath.lastIndexOf("."));
path = fullpath.substring((RepositoryController.CONTROLLER_URL + "/download/d").length(), fullpath.lastIndexOf("/"));
if (LOG.isDebugEnabled()) {
LOG.debug("{} {}", path, uuid + ext);
}
} catch (ArrayIndexOutOfBoundsException e) {
// fullpath.lastIndexOf may return -1, causing AIOBE
throw new ResourceNotFoundException("No such resource " + fullpath);
}
final RepositoryFile repositoryFile = this.repositoryService.getFile(UUID.fromString(uuid));
sanityCheck(Paths.get(path), ext, repositoryFile);
return repositoryFile;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment