Commit a3dbadd7 authored by Matija Obreza's avatar Matija Obreza
Browse files

Moved institute files to /wiews/INSTCODE

parent 678f3992
/*
* 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.aspect;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.model.ImageGallery;
import org.genesys.filerepository.model.RepositoryImage;
import org.genesys.filerepository.service.ImageGalleryService;
import org.genesys.filerepository.service.aspect.AbstractImageGalleryAspects;
import org.genesys.filerepository.service.aspect.ImageGalleryAspectsImpl;
import org.genesys2.server.service.InstituteFilesService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
@Aspect
public class GenesysImageGalleryAspects extends AbstractImageGalleryAspects implements InitializingBean {
public static final Logger LOG = LoggerFactory.getLogger(GenesysImageGalleryAspects.class);
private static final Pattern ACCESSION_IMAGE_PATTERN = Pattern.compile(InstituteFilesService.REPOSITORY_INSTITUTE_PREFIX + "([A-Z]{3}\\d+)"
+ InstituteFilesService.REPOSITORY_INSTITUTE_ACCESSIONFILES + "/(.+)");
private ImageGalleryAspectsImpl imageGalleryAspect = new ImageGalleryAspectsImpl();
@Autowired
private InstituteFilesService instituteFilesService;
@Autowired
private ImageGalleryService imageGalleryService;
public GenesysImageGalleryAspects() {
LOG.warn("Instantiating {}", getClass().getName());
}
@Override
public void afterPropertiesSet() throws Exception {
LOG.warn("Instantiating bean {}", getClass().getName());
imageGalleryAspect.setImageGalleryService(imageGalleryService);
}
@Override
public Object afterRepositoryImageSaveIterable(JoinPoint joinPoint, Iterable<RepositoryImage> repositoryImages) throws Throwable {
if (repositoryImages != null) {
repositoryImages.forEach(ri -> {
ensureImageGallery(ri);
});
}
return super.afterRepositoryImageSaveIterable(joinPoint, repositoryImages);
}
@Override
@AfterReturning(value = "execution(* org.genesys.filerepository.persistence.RepositoryImagePersistence.save(*))", returning = "repositoryImage")
public Object afterRepositoryImageSave(JoinPoint joinPoint, RepositoryImage repositoryImage) throws Throwable {
ensureImageGallery(repositoryImage);
return super.afterRepositoryImageSave(joinPoint, repositoryImage);
}
@Override
@Around(value = "execution(* org.genesys.filerepository.persistence.RepositoryImagePersistence.delete(*)) && args(repositoryImage)")
public Object aroundRepositoryImageDelete(ProceedingJoinPoint joinPoint, RepositoryImage repositoryImage) throws Throwable {
return super.aroundRepositoryImageDelete(joinPoint, repositoryImage);
}
/**
* Ensures that an {@link ImageGallery} exists for accession images
*
* @param repositoryImage
*/
private void ensureImageGallery(RepositoryImage repositoryImage) {
LOG.trace(repositoryImage.getPath());
Matcher matcher = ACCESSION_IMAGE_PATTERN.matcher(repositoryImage.getPath());
if (matcher.matches()) {
LOG.debug("Path {} is within institute accession images prefix instCode={} acceNumb={}", repositoryImage.getPath(), matcher.group(1), matcher.group(2));
try {
instituteFilesService.createImageGallery(matcher.group(1), matcher.group(2));
} catch (InvalidRepositoryPathException e) {
LOG.warn("Error creating accession image gallery at {}, error is {}", repositoryImage.getPath(), e.getMessage());
}
}
}
@Override
protected void addImageToGallery(RepositoryImage repositoryImage) {
imageGalleryAspect.addImageToGallery(repositoryImage);
}
@Override
protected void removeImageFromGallery(RepositoryImage repositoryImage) {
imageGalleryAspect.removeImageFromGallery(repositoryImage);
}
}
......@@ -34,23 +34,36 @@ import org.springframework.data.domain.Pageable;
*/
public interface InstituteFilesService {
ImageGallery loadImageGallery(FaoInstitute institute, Accession accession);
/**
* The repository root path for files belonging to FaoInstitutes
*/
public static final String REPOSITORY_INSTITUTE_PREFIX = "/wiews/";
RepositoryImage getImage(FaoInstitute institute, Accession accession, UUID uuid) throws NoSuchRepositoryFileException;
/**
* Folder within {@link #REPOSITORY_INSTITUTE_PREFIX}/INSTCODE that contains accession-specific files
*/
public static final String REPOSITORY_INSTITUTE_ACCESSIONFILES = "/acn";
RepositoryImage updateImageMetadata(FaoInstitute institute, Accession accession, UUID uuid, RepositoryImage repositoryImage) throws NoSuchRepositoryFileException;
ImageGallery loadImageGallery(FaoInstitute institute, Accession accession) throws InvalidRepositoryPathException;
RepositoryImage getImage(FaoInstitute institute, Accession accession, UUID uuid) throws NoSuchRepositoryFileException, InvalidRepositoryPathException;
RepositoryImage updateImageMetadata(FaoInstitute institute, Accession accession, UUID uuid, RepositoryImage repositoryImage) throws NoSuchRepositoryFileException, InvalidRepositoryPathException;
byte[] getFileBytes(FaoInstitute institute, Accession accession, RepositoryImage repositoryImage) throws NoSuchRepositoryFileException, IOException;
Page<ImageGallery> listImageGalleries(FaoInstitute institute, Pageable pageable);
ImageGallery createImageGallery(FaoInstitute institute, Accession accession);
ImageGallery createImageGallery(FaoInstitute institute, Accession accession) throws InvalidRepositoryPathException;
RepositoryImage addImage(FaoInstitute institute, Accession accession, String originalFilename, String contentType, byte[] bytes) throws InvalidRepositoryPathException, InvalidRepositoryFileDataException, IOException;
ImageGallery createImageGallery(String instCode, String acceNumb) throws InvalidRepositoryPathException;
RepositoryImage updateImage(FaoInstitute institute, Accession accession, RepositoryImage repositoryImage, String contentType, byte[] bytes) throws NoSuchRepositoryFileException, IOException;
RepositoryImage addImage(FaoInstitute institute, Accession accession, String originalFilename, String contentType, byte[] bytes) throws InvalidRepositoryPathException,
InvalidRepositoryFileDataException, IOException;
RepositoryImage deleteImage(FaoInstitute institute, Accession accession, RepositoryImage repositoryImage) throws NoSuchRepositoryFileException, IOException;
RepositoryImage updateImage(FaoInstitute institute, Accession accession, RepositoryImage repositoryImage, String contentType, byte[] bytes) throws NoSuchRepositoryFileException,
IOException;
RepositoryImage deleteImage(FaoInstitute institute, Accession accession, RepositoryImage repositoryImage) throws NoSuchRepositoryFileException, IOException;
}
......@@ -19,6 +19,7 @@ package org.genesys2.server.service.impl;
import java.io.IOException;
import java.util.UUID;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.genesys.filerepository.InvalidRepositoryFileDataException;
......@@ -45,9 +46,8 @@ import org.springframework.stereotype.Service;
@Service
public class InstituteFilesServiceImpl implements InstituteFilesService {
public static final Log LOG = LogFactory.getLog(InstituteFilesServiceImpl.class);
private static final String REPOSITORY_GALLERIES_PREFIX = "/accessions/";
public static final Log LOG = LogFactory.getLog(InstituteFilesServiceImpl.class);
private static final String ACCESSION_GALLERY_TITLE_FORMAT = "%1s image gallery";
......@@ -59,36 +59,51 @@ public class InstituteFilesServiceImpl implements InstituteFilesService {
@Autowired
private ImageGalleryService imageGalleryService;
private static final String getGalleriesPrefix(final FaoInstitute institute) {
return REPOSITORY_GALLERIES_PREFIX + institute.getCode() + "/acn";
/**
* @param instCode INSTCODE
* @return
*/
private static final String getGalleriesPrefix(final String instCode) {
return REPOSITORY_INSTITUTE_PREFIX + instCode + REPOSITORY_INSTITUTE_ACCESSIONFILES;
}
private static final String getGalleryPath(final FaoInstitute institute, final Accession accession) {
return getGalleriesPrefix(institute) + "/" + accession.getAccessionName();
private static final String getGalleryPath(final FaoInstitute institute, final Accession accession) throws InvalidRepositoryPathException {
return getGalleryPath(institute.getCode(), accession.getAccessionName());
}
public static final String getGalleryPath(final String instCode, final String acceNumb) throws InvalidRepositoryPathException {
if (StringUtils.contains(acceNumb, "/")) {
throw new InvalidRepositoryPathException("ACCENUMB contains /, cannot create gallery for " + acceNumb);
}
return getGalleriesPrefix(instCode) + "/" + acceNumb;
}
@Override
public Page<ImageGallery> listImageGalleries(FaoInstitute institute, Pageable pageable) {
return imageGalleryService.listImageGalleries(getGalleriesPrefix(institute), pageable);
return imageGalleryService.listImageGalleries(getGalleriesPrefix(institute.getCode()), pageable);
}
@Override
public ImageGallery loadImageGallery(final FaoInstitute institute, final Accession accession) {
public ImageGallery loadImageGallery(final FaoInstitute institute, final Accession accession) throws InvalidRepositoryPathException {
final String path = getGalleryPath(institute, accession);
return this.imageGalleryService.loadImageGallery(path);
}
@Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#institute, 'WRITE') or hasPermission(#institute, 'CREATE')")
public ImageGallery createImageGallery(FaoInstitute institute, Accession accession) {
final String path = getGalleryPath(institute, accession);
public ImageGallery createImageGallery(FaoInstitute institute, Accession accession) throws InvalidRepositoryPathException {
return createImageGallery(institute.getCode(), accession.getAccessionName());
}
return this.imageGalleryService.createImageGallery(path, String.format(ACCESSION_GALLERY_TITLE_FORMAT, accession.getAccessionName()), ACCESSION_GALLERY_DESCRIPTION);
@Override
public ImageGallery createImageGallery(String instCode, String acceNumb) throws InvalidRepositoryPathException {
return this.imageGalleryService.createImageGallery(getGalleryPath(instCode, acceNumb), String.format(ACCESSION_GALLERY_TITLE_FORMAT, acceNumb), ACCESSION_GALLERY_DESCRIPTION);
}
@Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#institute, 'WRITE') or hasPermission(#institute, 'CREATE')")
public RepositoryImage getImage(final FaoInstitute institute, final Accession accession, final UUID uuid) throws NoSuchRepositoryFileException {
public RepositoryImage getImage(final FaoInstitute institute, final Accession accession, final UUID uuid) throws NoSuchRepositoryFileException, InvalidRepositoryPathException {
final RepositoryFile repositoryFile = this.repositoryService.getFile(uuid);
if (!repositoryFile.getPath().equals(getGalleryPath(institute, accession))) {
......@@ -102,7 +117,7 @@ public class InstituteFilesServiceImpl implements InstituteFilesService {
@Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#institute, 'WRITE') or hasPermission(#institute, 'CREATE')")
public RepositoryImage updateImageMetadata(final FaoInstitute institute, Accession accession, final UUID uuid, final RepositoryImage imageData) throws NoSuchRepositoryFileException {
public RepositoryImage updateImageMetadata(final FaoInstitute institute, Accession accession, final UUID uuid, final RepositoryImage imageData) throws NoSuchRepositoryFileException, InvalidRepositoryPathException {
final RepositoryFile repositoryFile = this.repositoryService.getFile(uuid);
if (!repositoryFile.getPath().equals(getGalleryPath(institute, accession))) {
LOG.warn(repositoryFile.getPath() + "!=" + getGalleryPath(institute, accession));
......
......@@ -25,6 +25,7 @@ import java.util.UUID;
import javax.servlet.http.HttpServletResponse;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.model.ImageGallery;
import org.genesys.filerepository.service.ImageGalleryService;
import org.genesys2.server.model.dataset.DS;
......@@ -193,7 +194,12 @@ public class AccessionController extends BaseController {
}
}
final ImageGallery imageGallery = this.instituteFilesService.loadImageGallery(accession.getInstitute(), accession);
ImageGallery imageGallery = null;
try {
imageGallery = this.instituteFilesService.loadImageGallery(accession.getInstitute(), accession);
} catch (InvalidRepositoryPathException e) {
_logger.warn("Error loading image gallery for accession={}. {}", accession.getAccessionName(), e.getMessage());
}
if (imageGallery != null) {
imageGalleryService.ensureThumbnails(imageGallery, 200, 200);
model.addAttribute("thumbnailFormat", "200x200");
......
......@@ -98,9 +98,10 @@ public class InstituteGalleriesController extends RestController {
* List UUIDs of images in the accession gallery for INSTCODE/acn/ACCENUMB
*
* @throws NonUniqueAccessionException
* @throws InvalidRepositoryPathException
*/
@RequestMapping(value = "/{instCode}/acn/{acceNumb:.+}/_list", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody List<UUID> listAccessionGallery(@PathVariable("instCode") final String instCode, @PathVariable("acceNumb") final String acceNumb) throws NonUniqueAccessionException {
public @ResponseBody List<UUID> listAccessionGallery(@PathVariable("instCode") final String instCode, @PathVariable("acceNumb") final String acceNumb) throws NonUniqueAccessionException, InvalidRepositoryPathException {
final FaoInstitute institute = this.instituteService.findInstitute(instCode);
final Accession accession = this.genesysService.getAccession(instCode, acceNumb);
......@@ -127,11 +128,12 @@ public class InstituteGalleriesController extends RestController {
* Update image metadata
*
* @throws NonUniqueAccessionException
* @throws InvalidRepositoryPathException
*/
@RequestMapping(value = "/{instCode}/acn/{acceNumb:.+}/{uuid}/_metadata", method = { RequestMethod.PUT }, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody RepositoryImage updateImageMetadata(final HttpServletRequest request, final HttpServletResponse response, @PathVariable("instCode") final String instCode,
@PathVariable("acceNumb") final String acceNumb, @PathVariable("uuid") final UUID uuid, @RequestBody final RepositoryImage imageData)
throws IOException, NonUniqueAccessionException {
throws IOException, NonUniqueAccessionException, InvalidRepositoryPathException {
final FaoInstitute institute = this.instituteService.findInstitute(instCode);
final Accession accession = this.genesysService.getAccession(instCode, acceNumb);
......@@ -161,10 +163,11 @@ public class InstituteGalleriesController extends RestController {
*
* @throws IOException
* @throws NonUniqueAccessionException
* @throws InvalidRepositoryPathException
*/
@RequestMapping(value = "/{instCode}/acn/{acceNumb:.+}/{uuid}/_metadata", method = { RequestMethod.GET }, produces = { MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody RepositoryImage getImageMetadata(final HttpServletRequest request, final HttpServletResponse response, @PathVariable("instCode") final String instCode,
@PathVariable("acceNumb") final String acceNumb, @PathVariable("uuid") final UUID uuid) throws IOException, NonUniqueAccessionException {
@PathVariable("acceNumb") final String acceNumb, @PathVariable("uuid") final UUID uuid) throws IOException, NonUniqueAccessionException, InvalidRepositoryPathException {
final FaoInstitute institute = this.instituteService.findInstitute(instCode);
final Accession accession = this.genesysService.getAccession(instCode, acceNumb);
......@@ -194,10 +197,11 @@ public class InstituteGalleriesController extends RestController {
*
* @throws IOException
* @throws NonUniqueAccessionException
* @throws InvalidRepositoryPathException
*/
@RequestMapping(value = "/{instCode}/acn/{acceNumb:.+}/{uuid}", method = { RequestMethod.GET })
public void getImage(final HttpServletRequest request, final HttpServletResponse response, @PathVariable("instCode") final String instCode, @PathVariable("acceNumb") final String acceNumb,
@PathVariable("uuid") final UUID uuid) throws IOException, NonUniqueAccessionException {
@PathVariable("uuid") final UUID uuid) throws IOException, NonUniqueAccessionException, InvalidRepositoryPathException {
final FaoInstitute institute = this.instituteService.findInstitute(instCode);
final Accession accession = this.genesysService.getAccession(instCode, acceNumb);
......@@ -234,10 +238,11 @@ public class InstituteGalleriesController extends RestController {
*
* @throws IOException
* @throws NonUniqueAccessionException
* @throws InvalidRepositoryPathException
*/
@RequestMapping(value = "/{instCode}/acn/{acceNumb:.+}/{uuid}", method = { RequestMethod.DELETE })
public void deleteImage(@PathVariable("instCode") final String instCode, @PathVariable("acceNumb") final String acceNumb,
@PathVariable("uuid") final UUID uuid) throws IOException, NonUniqueAccessionException {
@PathVariable("uuid") final UUID uuid) throws IOException, NonUniqueAccessionException, InvalidRepositoryPathException {
final FaoInstitute institute = this.instituteService.findInstitute(instCode);
final Accession accession = this.genesysService.getAccession(instCode, acceNumb);
......
......@@ -38,7 +38,6 @@ import org.genesys.filerepository.service.BytesStorageService;
import org.genesys.filerepository.service.ImageGalleryService;
import org.genesys.filerepository.service.RepositoryService;
import org.genesys.filerepository.service.ThumbnailGenerator;
import org.genesys.filerepository.service.aspect.ImageGalleryAspects;
import org.genesys.filerepository.service.ftp.FtpUser;
import org.genesys.filerepository.service.ftp.RepositoryFileSystemFactory;
import org.genesys.filerepository.service.ftp.RepositoryFtpServer;
......@@ -48,6 +47,7 @@ import org.genesys.filerepository.service.impl.ImageGalleryServiceImpl;
import org.genesys.filerepository.service.impl.RepositoryServiceImpl;
import org.genesys.filerepository.service.impl.S3StorageServiceImpl;
import org.genesys.filerepository.service.impl.ThumbnailGenerator1;
import org.genesys2.server.aspect.GenesysImageGalleryAspects;
import org.genesys2.server.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -122,7 +122,7 @@ public class FileRepositoryConfig implements InitializingBean {
} else {
repoDir = new File(FileUtils.getTempDirectory(), "repository");
}
LOG.warn("Initializing filesystem bytes storage at base path={}", repoDir.getAbsolutePath());
storageService.setRepositoryBaseDirectory(repoDir);
......@@ -162,8 +162,8 @@ public class FileRepositoryConfig implements InitializingBean {
* @return the image gallery aspects
*/
@Bean
public ImageGalleryAspects imageGalleryAspects() {
return new ImageGalleryAspects();
public GenesysImageGalleryAspects imageGalleryAspects() {
return new GenesysImageGalleryAspects();
}
@Bean
......
......@@ -39,12 +39,12 @@ import org.genesys.filerepository.service.BytesStorageService;
import org.genesys.filerepository.service.ImageGalleryService;
import org.genesys.filerepository.service.RepositoryService;
import org.genesys.filerepository.service.ThumbnailGenerator;
import org.genesys.filerepository.service.aspect.ImageGalleryAspects;
import org.genesys.filerepository.service.impl.FilesystemStorageServiceImpl;
import org.genesys.filerepository.service.impl.ImageGalleryServiceImpl;
import org.genesys.filerepository.service.impl.RepositoryServiceImpl;
import org.genesys.filerepository.service.impl.ThumbnailGenerator1;
import org.genesys2.server.aspect.AsAdminAspect;
import org.genesys2.server.aspect.GenesysImageGalleryAspects;
import org.genesys2.server.persistence.domain.AccessionHistoricRepository;
import org.genesys2.server.persistence.domain.AccessionRepository;
import org.genesys2.server.persistence.domain.ArticleRepository;
......@@ -136,10 +136,9 @@ public abstract class GenesysServicesTest extends BaseSpringTest {
public static class Config {
@Bean
public ImageGalleryAspects imageGalleryAspects() {
public GenesysImageGalleryAspects imageGalleryAspects() {
// This thing makes galleries auto-fill with images
System.err.println("imagegalleryaspects");
return new ImageGalleryAspects();
return new GenesysImageGalleryAspects();
}
@Bean
......
......@@ -39,13 +39,13 @@ import org.genesys.filerepository.service.BytesStorageService;
import org.genesys.filerepository.service.ImageGalleryService;
import org.genesys.filerepository.service.RepositoryService;
import org.genesys.filerepository.service.ThumbnailGenerator;
import org.genesys.filerepository.service.aspect.ImageGalleryAspects;
import org.genesys.filerepository.service.impl.FilesystemStorageServiceImpl;
import org.genesys.filerepository.service.impl.ImageGalleryServiceImpl;
import org.genesys.filerepository.service.impl.RepositoryServiceImpl;
import org.genesys.filerepository.service.impl.ThumbnailGenerator1;
import org.genesys2.brapi.service.impl.BrAPIServiceImpl;
import org.genesys2.server.aspect.AsAdminAspect;
import org.genesys2.server.aspect.GenesysImageGalleryAspects;
import org.genesys2.server.persistence.domain.AccessionHistoricRepository;
import org.genesys2.server.persistence.domain.AccessionRepository;
import org.genesys2.server.persistence.domain.ArticleRepository;
......@@ -191,10 +191,9 @@ public abstract class AbstractRestTest extends BaseSpringTest {
public static class Config {
@Bean
public ImageGalleryAspects imageGalleryAspects() {
public GenesysImageGalleryAspects imageGalleryAspects() {
// This thing makes galleries auto-fill with images
System.err.println("imagegalleryaspects");
return new ImageGalleryAspects();
return new GenesysImageGalleryAspects();
}
@Bean
......
......@@ -156,7 +156,7 @@ public class ApiImagesDocsTest extends AbstractRestTest {
RepositoryImage ri = objectMapper.readValue(r.getResponse().getContentAsString(), RepositoryImage.class);
LOG.info(ri);
sb.append(ri.getUuid());
}).andExpect(jsonPath("$.id", greaterThan(0))).andExpect(jsonPath("$.path", is("/accessions/" + TEST_INSTCODE + "/acn/" + ACCENUMB)))
}).andExpect(jsonPath("$.id", greaterThan(0))).andExpect(jsonPath("$.path", is("/wiews/" + TEST_INSTCODE + "/acn/" + ACCENUMB)))
.andExpect(jsonPath("$.originalFilename", is(image1.getOriginalFilename()))).andExpect(jsonPath("$.contentType", is("image/jpeg")))
.andDo(document("img-instgallery-put",
pathParameters(parameterWithName("instCode").description("Institute WIEWS code (e.g. NGA039)"),
......
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