Commit cb60773c authored by Maxym Borodenko's avatar Maxym Borodenko Committed by Matija Obreza

Descriptor image and language

parent 0e1cbea6
......@@ -23,6 +23,7 @@ import org.genesys.catalog.model.Partner;
import org.genesys.catalog.model.dataset.Dataset;
import org.genesys.catalog.model.vocab.ControlledVocabulary;
import org.genesys.catalog.model.vocab.VocabularyTerm;
import org.genesys.filerepository.model.RepositoryImage;
import org.genesys2.server.model.PublishState;
import org.genesys2.server.model.impl.Crop;
import org.springframework.dao.DataIntegrityViolationException;
......@@ -221,6 +222,13 @@ public class Descriptor extends UuidModel implements SelfCleaning, Publishable,
@Column(length = 20, nullable = false)
private Category category;
@Size(max = 2)
private String lang;
@OneToOne(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, optional = true, orphanRemoval = true)
@JoinColumn(name = "imageId", unique = true)
private RepositoryImage image;
/**
* Instantiates a new descriptor.
*/
......@@ -252,7 +260,7 @@ public class Descriptor extends UuidModel implements SelfCleaning, Publishable,
public Descriptor(final Descriptor descriptor) {
this(descriptor.getVersionTag(), descriptor.getTitle(), descriptor.description, descriptor.getDataType(), descriptor.getState(), descriptor.isKey(), descriptor
.getIntegerOnly(), descriptor.getMinValue(), descriptor.getMaxValue(), descriptor.getColumnName(), descriptor.getUom(), descriptor.getVocabulary(), descriptor
.getOwner(), descriptor.getDescriptorLists());
.getOwner(), descriptor.getDescriptorLists(), descriptor.getImage());
}
/**
......@@ -272,10 +280,11 @@ public class Descriptor extends UuidModel implements SelfCleaning, Publishable,
* @param vocabulary the vocabulary
* @param owner the owner
* @param descriptorLists the descriptor lists
* @param image the image
*/
public Descriptor(final String versionTag, final String title, final String description, final DataType dataType, final PublishState state, final boolean key,
final Boolean integerOnly, final Double minValue, final Double maxValue, final String columnName, final String uom, final ControlledVocabulary vocabulary,
final Partner owner, final List<DescriptorList> descriptorLists) {
final Partner owner, final List<DescriptorList> descriptorLists, final RepositoryImage image) {
this.versionTag = versionTag;
this.title = title;
this.description = description;
......@@ -290,6 +299,7 @@ public class Descriptor extends UuidModel implements SelfCleaning, Publishable,
this.vocabulary = vocabulary;
this.owner = owner;
this.descriptorLists = descriptorLists;
this.image = image;
}
/**
......@@ -674,6 +684,42 @@ public class Descriptor extends UuidModel implements SelfCleaning, Publishable,
this.category = category;
}
/**
* Gets the lang.
*
* @return the lang
*/
public String getLang() {
return lang;
}
/**
* Sets the lang.
*
* @param lang the new lang
*/
public void setLang(final String lang) {
this.lang = lang;
}
/**
* Gets the image.
*
* @return the image
*/
public RepositoryImage getImage() {
return image;
}
/**
* Sets the image.
*
* @param image the new repository image
*/
public void setImage(final RepositoryImage image) {
this.image = image;
}
/*
* (non-Javadoc)
* @see org.genesys.blocks.model.Copyable#copy()
......
......@@ -19,10 +19,15 @@ import org.genesys.catalog.model.dataset.Dataset;
import org.genesys.catalog.model.filters.DescriptorFilter;
import org.genesys.catalog.model.traits.Descriptor;
import org.genesys.catalog.model.traits.DescriptorList;
import org.genesys.filerepository.InvalidRepositoryFileDataException;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.NoSuchRepositoryFileException;
import org.genesys.filerepository.model.RepositoryImage;
import org.genesys2.server.exception.NotFoundElement;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.method.P;
import org.springframework.web.multipart.MultipartFile;
import javax.validation.Valid;
import java.io.IOException;
......@@ -51,6 +56,30 @@ public interface DescriptorService {
*/
List<Descriptor> searchMatchingDescriptor(Descriptor descriptor);
/**
* Updates the image of descriptor.
*
* @param descriptor the descriptor
* @param file image file that be added to Db and descriptor
* @param imageMetadata the updated image metadata
* @return updated descriptor
* @throws IOException IOException
* @throws InvalidRepositoryPathException InvalidRepositoryPathException
* @throws InvalidRepositoryFileDataException InvalidRepositoryFileDataException
* @throws NoSuchRepositoryFileException the no such repository file exception
*/
Descriptor updateImage(Descriptor descriptor, MultipartFile file, RepositoryImage imageMetadata) throws IOException, InvalidRepositoryPathException, InvalidRepositoryFileDataException, NoSuchRepositoryFileException;
/**
* Removes the image of descriptor.
*
* @param descriptor the descriptor
* @return updated descriptor
* @throws NoSuchRepositoryFileException NoSuchRepositoryFileException
* @throws IOException IOException
*/
Descriptor removeImage(Descriptor descriptor) throws NoSuchRepositoryFileException, IOException;
/**
* Update descriptor.
*
......
......@@ -248,7 +248,12 @@ public class DescriptorListServiceImpl implements DescriptorListService {
if (descriptorList.getDescriptors() != null) {
descriptorList.getDescriptors().size();
descriptorList.getDescriptors().forEach(descriptor -> descriptor.getTerms().size());
descriptorList.getDescriptors().forEach(descriptor -> {
descriptor.getTerms().size();
if (descriptor.getImage() != null) {
descriptor.getImage().getId();
}
});
}
if (descriptorList.getOwner() != null) {
descriptorList.getOwner().getId();
......
......@@ -19,6 +19,8 @@ import static org.genesys.catalog.model.traits.QDescriptor.descriptor;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
......@@ -40,6 +42,11 @@ import org.genesys.catalog.persistence.traits.DescriptorRepository;
import org.genesys.catalog.persistence.vocab.VocabularyTermRepository;
import org.genesys.catalog.service.DescriptorService;
import org.genesys.catalog.service.VersionManager;
import org.genesys.filerepository.InvalidRepositoryFileDataException;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.NoSuchRepositoryFileException;
import org.genesys.filerepository.model.RepositoryImage;
import org.genesys.filerepository.service.RepositoryService;
import org.genesys2.server.component.security.SecurityUtils;
import org.genesys2.server.exception.InvalidApiUsageException;
import org.genesys2.server.exception.NotFoundElement;
......@@ -69,6 +76,7 @@ import org.springframework.validation.annotation.Validated;
import com.google.common.collect.Lists;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Predicate;
import org.springframework.web.multipart.MultipartFile;
/**
* The Class DescriptorServiceImpl.
......@@ -106,6 +114,10 @@ public class DescriptorServiceImpl implements DescriptorService {
@Autowired
private ElasticsearchService elasticsearchService;
/** The file repo service. */
@Autowired
private RepositoryService repositoryService;
/**
* {@inheritDoc}
*/
......@@ -166,6 +178,72 @@ public class DescriptorServiceImpl implements DescriptorService {
return matches;
}
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#descriptor, 'write')")
public Descriptor updateImage(Descriptor descriptor, final MultipartFile file, final RepositoryImage imageMetadata) throws IOException,
InvalidRepositoryPathException, InvalidRepositoryFileDataException, NoSuchRepositoryFileException {
descriptor = descriptorRepository.findByUuidAndVersion(descriptor.getUuid(), descriptor.getVersion());
if (descriptor.isPublished()) {
throw new InvalidApiUsageException("Cannot modify a published Descriptor.");
}
if (! file.getContentType().startsWith("image/")) {
throw new InvalidApiUsageException("Invalid image type: " + file.getContentType() + " is not permitted.");
}
RepositoryImage repositoryImage = descriptor.getImage();
if (repositoryImage == null) {
String originalFilename = file.getOriginalFilename();
String ext = "";
if (originalFilename != null) {
int dotIndex = originalFilename.lastIndexOf(".");
ext = dotIndex > 0 ? originalFilename.substring(dotIndex) : "";
}
repositoryImage = repositoryService.addImage(getRepositoryImageFolder(descriptor),
descriptor.getUuid().toString() + ext, file.getContentType(), file.getBytes(), imageMetadata);
descriptor.setImage(repositoryImage);
return lazyLoad(descriptorRepository.save(descriptor));
}
String imageName = repositoryImage.getOriginalFilename();
descriptor = removeImage(descriptor);
RepositoryImage newImage = repositoryService.addImage(getRepositoryImageFolder(descriptor),
imageName, file.getContentType(), file.getBytes(), imageMetadata);
descriptor.setImage(newImage);
return lazyLoad(descriptorRepository.save(descriptor));
}
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#descriptor, 'write')")
public Descriptor removeImage(Descriptor descriptor) throws NoSuchRepositoryFileException, IOException {
descriptor = descriptorRepository.findByUuidAndVersion(descriptor.getUuid(), descriptor.getVersion());
if (descriptor.isPublished()) {
throw new InvalidApiUsageException("Cannot modify a published Descriptor.");
}
final RepositoryImage repositoryImage = descriptor.getImage();
if (repositoryImage != null) {
repositoryService.removeImage(repositoryImage);
descriptor.setImage(null);
}
return lazyLoad(descriptorRepository.save(descriptor));
}
private Path getRepositoryImageFolder(final Descriptor descriptor) {
assert (descriptor != null);
assert (descriptor.getUuid() != null);
String uuid = descriptor.getUuid().toString();
return Paths.get("/descriptor", uuid.substring(0, 3), uuid).toAbsolutePath();
}
/**
* Persist or update terms in descriptor itself. It updates descriptor's own
* terms List
......@@ -364,6 +442,10 @@ public class DescriptorServiceImpl implements DescriptorService {
}
}
if (descriptor.getImage() != null) {
descriptor.getImage().getId();
}
return descriptor;
}
......
......@@ -34,10 +34,15 @@ import org.genesys.catalog.model.traits.DescriptorList;
import org.genesys.catalog.service.DescriptorService;
import org.genesys.catalog.service.ShortFilterService;
import org.genesys.catalog.service.ShortFilterService.FilterInfo;
import org.genesys.filerepository.InvalidRepositoryFileDataException;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.NoSuchRepositoryFileException;
import org.genesys.filerepository.model.RepositoryImage;
import org.genesys2.server.api.ApiBaseController;
import org.genesys2.server.api.FilteredPage;
import org.genesys2.server.api.Pagination;
import org.genesys2.server.exception.InvalidApiUsageException;
import org.genesys2.server.exception.NotFoundElement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.Sort;
......@@ -50,7 +55,9 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
/**
* The Class DescriptorController.
......@@ -67,6 +74,7 @@ public class DescriptorController extends ApiBaseController {
/** The Constant API_BASE. */
public static final String CONTROLLER_URL = ApiBaseController.APIv1_BASE + "/descriptor";
public static final String IMAGE_URL = "/{uuid}/image";
@Autowired
private DescriptorService descriptorService;
......@@ -335,6 +343,17 @@ public class DescriptorController extends ApiBaseController {
};
}
@PostMapping(value = IMAGE_URL)
public Descriptor updateImage(@PathVariable("uuid") final UUID descriptorUuid, @RequestPart(name = "image", required = true) final MultipartFile image,
@RequestPart(name = "metadata", required = false) final RepositoryImage metadata) throws InvalidRepositoryPathException,
InvalidRepositoryFileDataException, IOException, NotFoundElement, NoSuchRepositoryFileException {
return descriptorService.updateImage(descriptorService.loadDescriptor(descriptorUuid), image, metadata);
}
@DeleteMapping(value = IMAGE_URL)
public Descriptor removeImage(@PathVariable("uuid") final UUID descriptorUuid) throws NoSuchRepositoryFileException, IOException, NotFoundElement {
return descriptorService.removeImage(descriptorService.loadDescriptor(descriptorUuid));
}
}
......@@ -108,8 +108,7 @@ public class DescriptorListController {
*/
@GetMapping(value = "/{uuid}")
public DescriptorList getDescriptorList(@PathVariable("uuid") final UUID uuid) {
final DescriptorList descriptorList = descriptorListService.getDescriptorList(uuid);
return descriptorList;
return descriptorListService.getDescriptorList(uuid);
}
/**
......@@ -183,8 +182,7 @@ public class DescriptorListController {
*/
@PostMapping(value = "/create")
public DescriptorList createDescriptorList(@RequestBody final DescriptorList source) {
final DescriptorList descriptorList = descriptorListService.createDescriptorList(source);
return descriptorList;
return descriptorListService.createDescriptorList(source);
}
/**
......@@ -195,8 +193,7 @@ public class DescriptorListController {
*/
@PostMapping(value = "/update")
public DescriptorList updateDescriptorList(@RequestBody final DescriptorList source) {
final DescriptorList descriptorList = descriptorListService.updateDescriptorList(source);
return descriptorList;
return descriptorListService.updateDescriptorList(source);
}
/**
......
......@@ -5817,3 +5817,21 @@ databaseChangeLog:
- sql:
sql: >-
CREATE INDEX IX_taxonName ON taxonomy2(taxonName(250))
- changeSet:
id: 1559809441738-1
author: mborodenko
changes:
- addColumn:
columns:
- column:
name: lang
type: VARCHAR(2)
- column:
name: imageId
type: BIGINT
tableName: descriptor
- addUniqueConstraint:
columnNames: imageId
constraintName: UK_p30ny8gip3fmcl83a0ot11a1
tableName: descriptor
......@@ -32,6 +32,7 @@ import java.util.UUID;
import org.genesys.filerepository.model.RepositoryImage;
import org.genesys.filerepository.persistence.ImageGalleryPersistence;
import org.genesys.filerepository.persistence.RepositoryFilePersistence;
import org.genesys.filerepository.persistence.RepositoryImagePersistence;
import org.genesys.test.base.AbstractApiTest;
import org.genesys2.server.model.genesys.Accession;
import org.genesys2.server.model.genesys.AccessionId;
......@@ -96,6 +97,8 @@ public class ApiImagesDocsTest extends AbstractApiTest {
@Autowired
private RepositoryFilePersistence repositoryFileRepository;
@Autowired
private RepositoryImagePersistence repositoryImagePersistence;
@Autowired
private GenesysService genesysService;
@Autowired
private TaxonomyService taxonomyService;
......@@ -143,6 +146,7 @@ public class ApiImagesDocsTest extends AbstractApiTest {
accessionIdRepository.deleteAll();
taxonomy2Repository.deleteAll();
instituteRepository.deleteAll();
repositoryImagePersistence.deleteAll();
imageGalleryPersistence.deleteAll();
repositoryFileRepository.deleteAll();
}
......
......@@ -24,12 +24,15 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
import java.util.UUID;
import com.google.common.collect.Lists;
import org.genesys.blocks.model.filters.StringFilter;
import org.genesys.catalog.model.traits.Descriptor;
import org.genesys.catalog.service.DescriptorService;
import org.genesys.filerepository.model.RepositoryImage;
import org.genesys2.server.api.v1.DescriptorListController;
import org.genesys.catalog.model.Partner;
import org.genesys.catalog.model.filters.DescriptorListFilter;
import org.genesys.catalog.model.traits.DescriptorList;
import org.genesys.catalog.persistence.PartnerRepository;
import org.genesys.catalog.persistence.traits.DescriptorListRepository;
import org.genesys.catalog.persistence.traits.DescriptorRepository;
import org.genesys.test.base.AbstractApiTest;
......@@ -41,12 +44,10 @@ import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.WebApplicationContext;
import com.fasterxml.jackson.core.JsonProcessingException;
......@@ -57,14 +58,9 @@ import com.fasterxml.jackson.core.JsonProcessingException;
public class DescriptorListControllerTest extends AbstractApiTest {
private static final String CROPNAME = "banana";
private static final String PARTNER_NAME = "Partner Name";
private static final String URL = "https://my-test-url.net";
@Autowired
private WebApplicationContext webApplicationContext;
@Autowired
private DescriptorListRepository descriptorListRepository;
......@@ -72,27 +68,14 @@ public class DescriptorListControllerTest extends AbstractApiTest {
private DescriptorRepository descriptorRepository;
@Autowired
private PartnerRepository partnerRepository;
MockMvc mockMvc;
private DescriptorService descriptorService;
private Partner partner;
@Before
@Transactional
public void setUp() {
{
final Partner partner = new Partner();
partner.setName(PARTNER_NAME);
partner.setActive(true);
partner.setShortName("P1");
partner.setUuid(UUID.randomUUID());
this.partner = partnerRepository.save(partner);
}
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).apply(documentationConfiguration(restDocumentation).uris().withScheme("https").withHost(
"api.catalog.genesys-pgr.org").withPort(443)).build();
this.partner = setUpPartner(PARTNER_NAME, true, "P1", UUID.randomUUID());
}
@After
......@@ -100,7 +83,6 @@ public class DescriptorListControllerTest extends AbstractApiTest {
public void cleanup() throws Exception {
descriptorListRepository.deleteAll();
descriptorRepository.deleteAll();
partnerRepository.deleteAll();
super.cleanup();
}
......@@ -123,6 +105,37 @@ public class DescriptorListControllerTest extends AbstractApiTest {
/*@formatter:on*/
}
@Test
@WithMockUser(username = "user", password = "user", roles = "ADMINISTRATOR")
public void getDescriptorListsWithDescriptorsTest() throws Exception {
Descriptor descriptor = descriptorService.createDescriptor(setUpDescriptor());
assertThat(descriptorRepository.count(), is(1L));
final MockMultipartFile image = new MockMultipartFile("image", "image.png", "image/png", new byte[1]);
final RepositoryImage imageMetadata = new RepositoryImage();
imageMetadata.setDescription("Test description of image.");
descriptor = descriptorService.updateImage(descriptor, image, imageMetadata);
DescriptorList descriptorList = setUpDescriptorList(PublishState.DRAFT, UUID.randomUUID(), "Des 2", "Title 2", "Vt 2");
descriptorList = descriptorListRepository.save(descriptorList);
assertThat(descriptorListRepository.count(), is(1L));
descriptorList.setDescriptors(Lists.newArrayList(descriptor));
descriptorList = descriptorListRepository.save(descriptorList);
/*@formatter:off*/
mockMvc
.perform(RestDocumentationRequestBuilders.get(DescriptorListController.CONTROLLER_URL + "/{uuid}", descriptorList.getUuid())
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
// .andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$", not(nullValue())))
.andExpect(jsonPath("$.uuid", is(descriptorList.getUuid().toString())))
.andExpect(jsonPath("$.descriptors[0].image", notNullValue()))
.andExpect(jsonPath("$.descriptors[0].image.description", is(imageMetadata.getDescription())))
.andDo(document("contract-roles-get"));
/*@formatter:on*/
}
@Test
@WithMockUser(username = "user", password = "user", roles = "ADMINISTRATOR")
public void updateDescriptorListTest() throws Exception {
......@@ -258,12 +271,11 @@ public class DescriptorListControllerTest extends AbstractApiTest {
public void getDescriptorListTest() throws Exception {
final DescriptorList descriptorList = setUpDescriptorList(PublishState.PUBLISHED, UUID.randomUUID(), "Des 2", "Title 2", "Vt 2");
descriptorListRepository.save(descriptorList);
final String s = verboseMapper.writeValueAsString(descriptorList);
assertThat(descriptorListRepository.count(), is(1L));
/*@formatter:off*/
mockMvc
.perform(RestDocumentationRequestBuilders.get(DescriptorListController.CONTROLLER_URL + "/{uuid}", descriptorList.getUuid())
.content(s)
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
// .andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
......
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