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

Merge branch '627-firstpublisheddate' into 'main'

Resolve "firstPublishedDate"

Closes #627

See merge request genesys-pgr/genesys-server!686
parents 2908cf73 ba76fe33
......@@ -15,7 +15,9 @@
*/
package org.genesys.catalog.model.dataset;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
......@@ -48,6 +50,7 @@ import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import org.genesys.blocks.annotations.NotCopyable;
import org.genesys.blocks.auditlog.annotations.Audited;
import org.genesys.blocks.model.JsonViews;
import org.genesys.blocks.model.Publishable;
......@@ -204,6 +207,10 @@ public class Dataset extends UuidModel implements Publishable, SelfCleaning, Acl
@Column(nullable = true, length = 200)
private String created;
@Column(name = "firstPublishedDate")
@NotCopyable
private Date firstPublishedDate;
/** The publish state. */
@Enumerated(EnumType.ORDINAL)
private PublishState state = PublishState.DRAFT;
......@@ -234,6 +241,9 @@ public class Dataset extends UuidModel implements Publishable, SelfCleaning, Acl
this.startDate = locations.stream().map(DatasetLocation::getStartDate).filter(d -> d != null).min(String::compareTo).orElse(null);
this.endDate = locations.stream().map(DatasetLocation::getEndDate).filter(d -> d != null).max(String::compareTo).orElse(null);
}
if (Objects.isNull(firstPublishedDate) && Objects.equals(state, PublishState.PUBLISHED)) {
firstPublishedDate = new Date();
}
trimStringsToNull();
}
......@@ -680,4 +690,13 @@ public class Dataset extends UuidModel implements Publishable, SelfCleaning, Acl
this.crops = crops;
}
/**
* Gets the first published date
*
* @return the first published date
*/
public Date getFirstPublishedDate() {
return firstPublishedDate;
}
}
......@@ -16,6 +16,7 @@
package org.genesys.catalog.model.traits;
import com.fasterxml.jackson.annotation.*;
import org.genesys.blocks.annotations.NotCopyable;
import org.genesys.blocks.auditlog.annotations.Audited;
import org.genesys.blocks.model.*;
import org.genesys.blocks.security.model.AclAwareModel;
......@@ -35,7 +36,9 @@ import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
* A single descriptor definition belonging to a single "owner".
......@@ -230,6 +233,10 @@ public class Descriptor extends UuidModel implements SelfCleaning, Publishable,
@JoinColumn(name = "imageId", unique = true)
private RepositoryImage image;
@Column(name = "firstPublishedDate")
@NotCopyable
private Date firstPublishedDate;
/**
* Instantiates a new descriptor.
*/
......@@ -242,6 +249,9 @@ public class Descriptor extends UuidModel implements SelfCleaning, Publishable,
@PrePersist
@PreUpdate
private void preupdate() {
if (Objects.isNull(firstPublishedDate) && Objects.equals(state, PublishState.PUBLISHED)) {
firstPublishedDate = new Date();
}
trimStringsToNull();
}
......@@ -728,6 +738,15 @@ public class Descriptor extends UuidModel implements SelfCleaning, Publishable,
this.image = image;
}
/**
* Gets the first published date
*
* @return the first published date
*/
public Date getFirstPublishedDate() {
return firstPublishedDate;
}
/*
* (non-Javadoc)
* @see org.genesys.blocks.model.Copyable#copy()
......
......@@ -15,8 +15,10 @@
*/
package org.genesys.catalog.model.traits;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
......@@ -40,6 +42,7 @@ import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.genesys.blocks.annotations.NotCopyable;
import org.genesys.blocks.auditlog.annotations.Audited;
import org.genesys.blocks.model.JsonViews;
import org.genesys.blocks.model.Publishable;
......@@ -148,12 +151,19 @@ public class DescriptorList extends UuidModel implements Publishable, SelfCleani
@Lob
private Map<Extra, String> extras;
@Column(name = "firstPublishedDate")
@NotCopyable
private Date firstPublishedDate;
/**
* Pre-persist, pre-update
*/
@PrePersist
@PreUpdate
private void preupdate() {
if (Objects.isNull(firstPublishedDate) && Objects.equals(state, PublishState.PUBLISHED)) {
firstPublishedDate = new Date();
}
trimStringsToNull();
}
......@@ -371,4 +381,14 @@ public class DescriptorList extends UuidModel implements Publishable, SelfCleani
public void setExtras(final Map<Extra, String> extras) {
this.extras = extras;
}
/**
* Gets the first published date
*
* @return the first published date
*/
public Date getFirstPublishedDate() {
return firstPublishedDate;
}
}
......@@ -17,7 +17,9 @@
package org.genesys2.server.model.impl;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
......@@ -43,6 +45,7 @@ import javax.persistence.UniqueConstraint;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.genesys.blocks.annotations.NotCopyable;
import org.genesys.blocks.auditlog.annotations.Audited;
import org.genesys.blocks.model.JsonViews;
import org.genesys.blocks.model.Publishable;
......@@ -177,6 +180,10 @@ public class Subset extends UuidModel implements AclAwareModel, Publishable, Sel
@Column(length = 200, nullable = true)
private String selectionMethod;
@Column(name = "firstPublishedDate")
@NotCopyable
private Date firstPublishedDate;
@Transient
private UUID currentVersion;
......@@ -200,6 +207,10 @@ public class Subset extends UuidModel implements AclAwareModel, Publishable, Sel
this.wiewsCode = this.institute.getCode();
}
if (Objects.isNull(firstPublishedDate) && Objects.equals(state, PublishState.PUBLISHED)) {
firstPublishedDate = new Date();
}
// if (this.getAccessionRefs() != null) {
// this.accessionCount = this.getAccessionRefs().size();
// }
......@@ -580,4 +591,13 @@ public class Subset extends UuidModel implements AclAwareModel, Publishable, Sel
this.selectionMethod = selectionMethod;
}
/**
* Gets the first published date
*
* @return the first published date
*/
public Date getFirstPublishedDate() {
return firstPublishedDate;
}
}
......@@ -7694,3 +7694,44 @@ databaseChangeLog:
- dropColumn:
columnName: tileIndex
tableName: accession
- changeSet:
id: 1645178438270-2
author: ahrybeniuk
changes:
- addColumn:
columns:
- column:
name: firstPublishedDate
type: datetime
tableName: dataset
- addColumn:
columns:
- column:
name: firstPublishedDate
type: datetime
tableName: subset
- addColumn:
columns:
- column:
name: firstPublishedDate
type: datetime
tableName: descriptorlist
- addColumn:
columns:
- column:
name: firstPublishedDate
type: datetime
tableName: descriptor
- sql:
comment: Sets firstPublishedDate = lastModifiedDate to datasets
sql: update dataset set firstPublishedDate = lastModifiedDate where state = 1
- sql:
comment: Sets firstPublishedDate = lastModifiedDate to subsets
sql: update subset set firstPublishedDate = lastModifiedDate where state = 1
- sql:
comment: Sets firstPublishedDate = lastModifiedDate to descriptorlists
sql: update descriptorlist set firstPublishedDate = lastModifiedDate where state = 1
- sql:
comment: Sets firstPublishedDate = lastModifiedDate to descriptors
sql: update descriptor set firstPublishedDate = lastModifiedDate where state = 1
\ No newline at end of file
......@@ -955,4 +955,68 @@ public class DatasetControllerTest extends AbstractDatasetControllerTest {
/*@formatter:on*/
}
@Test
@WithMockUser(username = "user", password = "user", roles = "ADMINISTRATOR")
public void firstPublishedDateTest() throws Exception {
Dataset dataset = setUpDataset();
// Create new Dataset
/*@formatter:off*/
mockMvc
.perform(RestDocumentationRequestBuilders.post(DatasetController.CONTROLLER_URL.concat("/create"))
.contentType(MediaType.APPLICATION_JSON)
.content(verboseMapper.writeValueAsString(dataset))
)
// .andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(jsonPath("$", not(nullValue())))
.andExpect(jsonPath("$.uuid", is(notNullValue())))
.andExpect(jsonPath("$.firstPublishedDate", is(nullValue())));
/*@formatter:on*/
assertThat(datasetRepository.count(), is(1L));
dataset = datasetRepository.findAll().get(0);
assertThat(dataset.getFirstPublishedDate(), is(nullValue()));
// Approve Dataset
dataset = datasetService.reviewDataset(dataset);
assertThat(dataset.getState(), is(PublishState.REVIEWING));
/*@formatter:off*/
mockMvc
.perform(post(DatasetController.CONTROLLER_URL.concat("/approve"))
.param("uuid", dataset.getUuid().toString())
.param("version", dataset.getVersion().toString()))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(jsonPath("$", not(nullValue())))
.andExpect(jsonPath("$.uuid", is(dataset.getUuid().toString())))
.andExpect(jsonPath("$.current", is(Boolean.TRUE)))
.andExpect(jsonPath("$.state", is(PublishState.PUBLISHED.name())))
.andExpect(jsonPath("$.firstPublishedDate", is(notNullValue())))
;
/*@formatter:on*/
assertEquals(datasetVersionsRepository.count(), 1);
Dataset publishedDataset = datasetVersionsRepository.findAll().stream().findFirst().get().getCurrentVersion();
assertEquals(publishedDataset.getUuid(), dataset.getUuid());
assertThat(publishedDataset.getFirstPublishedDate(), is(notNullValue()));
// Create new version of Dataset
/*@formatter:off*/
mockMvc.perform(post(DatasetController.CONTROLLER_URL.concat("/create-new-version"))
.param("uuid", publishedDataset.getUuid().toString())
.contentType(MediaType.APPLICATION_JSON))
// .andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(jsonPath("$.firstPublishedDate", is(nullValue())))
;
/*@formatter:on*/
}
}
......@@ -19,15 +19,18 @@ package org.genesys.test.server.api.v1;
import static org.hamcrest.MatcherAssert.*;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.genesys.catalog.model.Partner;
import org.genesys.catalog.model.dataset.Dataset;
import org.genesys.catalog.model.filters.DescriptorFilter;
import org.genesys.catalog.model.filters.PartnerFilter;
import org.genesys.catalog.model.traits.Descriptor;
......@@ -41,6 +44,7 @@ import org.genesys.filerepository.NoSuchRepositoryFileException;
import org.genesys.filerepository.model.RepositoryImage;
import org.genesys.test.base.AbstractApiTest;
import org.genesys.test.base.WithMockOAuth2Authentication;
import org.genesys2.server.api.v1.DatasetController;
import org.genesys2.server.api.v1.DescriptorController;
import org.genesys2.server.model.PublishState;
import org.genesys2.server.model.impl.DownloadLog;
......@@ -498,6 +502,71 @@ public class DescriptorControllerTest extends AbstractApiTest {
/*@formatter:on*/
}
@Test
public void firstPublishedDateTest() throws Exception {
// Create new Descriptor
Descriptor descriptor = setUpDescriptor(PublishState.DRAFT);
final String s = verboseMapper.writeValueAsString(descriptor);
/*@formatter:off*/
mockMvc
.perform(RestDocumentationRequestBuilders.post(DescriptorController.CONTROLLER_URL + "/create")
.content(s)
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
// .andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(jsonPath("$", not(nullValue())))
.andExpect(jsonPath("$.lang", is(LANGUAGE)))
.andExpect(jsonPath("$.crop", is(CROPNAME)))
.andExpect(jsonPath("$.firstPublishedDate", is(nullValue())))
;
/*@formatter:on*/
assertThat(descriptorRepository.count(), is(1L));
descriptor = descriptorRepository.findAll().get(0);
assertThat(descriptor.getFirstPublishedDate(), is(nullValue()));
// Approve Descriptor
descriptor = descriptorService.reviewDescriptor(descriptor);
assertThat(descriptor.getState(), is(PublishState.REVIEWING));
/*@formatter:off*/
mockMvc
.perform(post(DescriptorController.CONTROLLER_URL.concat("/approve"))
.param("uuid", descriptor.getUuid().toString())
.param("version", descriptor.getVersion().toString()))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(jsonPath("$", not(nullValue())))
.andExpect(jsonPath("$.uuid", is(descriptor.getUuid().toString())))
.andExpect(jsonPath("$.state", is(PublishState.PUBLISHED.name())))
.andExpect(jsonPath("$.firstPublishedDate", is(notNullValue())))
;
/*@formatter:on*/
assertEquals(descriptorRepository.count(), 1);
Descriptor publishedDescriptor = descriptorService.loadDescriptor(descriptor.getUuid());
assertThat(publishedDescriptor.getFirstPublishedDate(), is(notNullValue()));
publishedDescriptor.getOwner().setUrls(Set.of());
// Create new version of Descriptor
/*@formatter:off*/
mockMvc.perform(post(DescriptorController.CONTROLLER_URL.concat("/copy"))
.contentType(MediaType.APPLICATION_JSON)
.content(verboseMapper.writeValueAsString(publishedDescriptor))
)
// .andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(jsonPath("$.firstPublishedDate", is(nullValue())))
;
/*@formatter:on*/
}
private Descriptor setUpDescriptor(final PublishState state) {
final Descriptor descriptor = new Descriptor();
descriptor.setOwner(partner);
......
......@@ -18,6 +18,7 @@ package org.genesys.test.server.api.v1;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
......@@ -25,8 +26,8 @@ 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.DescriptorListService;
import org.genesys.catalog.service.DescriptorService;
import org.genesys.filerepository.model.RepositoryImage;
import org.genesys2.server.api.v1.DescriptorListController;
......@@ -70,6 +71,9 @@ public class DescriptorListControllerTest extends AbstractApiTest {
@Autowired
private DescriptorService descriptorService;
@Autowired
private DescriptorListService descriptorListService;
private Partner partner;
@Before
......@@ -399,6 +403,58 @@ public class DescriptorListControllerTest extends AbstractApiTest {
/*@formatter:on*/
}
@Test
public void firstPublishedDateTest() throws Exception {
// Create new DescriptorList
DescriptorList descriptorList = setUpDescriptorList(PublishState.DRAFT, UUID.randomUUID(), "Des 1", "Title 1", "Vt 1");
final String s = verboseMapper.writeValueAsString(descriptorList);
/*@formatter:off*/
mockMvc
.perform(RestDocumentationRequestBuilders.post(DescriptorListController.CONTROLLER_URL + "/create")
.content(s)
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
// .andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(jsonPath("$", not(nullValue())))
.andExpect(jsonPath("$.url", is(URL)))
.andExpect(jsonPath("$.crop", is(CROPNAME)))
.andExpect(jsonPath("$.descriptors").doesNotExist()) // Must not return descriptors
.andExpect(jsonPath("$.firstPublishedDate", is(nullValue())))
;
/*@formatter:on*/
assertThat(descriptorListRepository.count(), is(1L));
descriptorList = descriptorListRepository.findAll().get(0);
assertThat(descriptorList.getFirstPublishedDate(), is(nullValue()));
// Approve DescriptorList
descriptorList = descriptorListService.reviewDescriptorList(descriptorList);
assertThat(descriptorList.getState(), is(PublishState.REVIEWING));
/*@formatter:off*/
mockMvc
.perform(post(DescriptorListController.CONTROLLER_URL.concat("/approve"))
.param("uuid", descriptorList.getUuid().toString())
.param("version", descriptorList.getVersion().toString()))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(jsonPath("$", not(nullValue())))
.andExpect(jsonPath("$.uuid", is(descriptorList.getUuid().toString())))
.andExpect(jsonPath("$.state", is(PublishState.PUBLISHED.name())))
.andExpect(jsonPath("$.firstPublishedDate", is(notNullValue())))
;
/*@formatter:on*/
assertEquals(descriptorListRepository.count(), 1);
DescriptorList publishedDescriptorList = descriptorListRepository.findAll().stream().findFirst().get();
assertEquals(publishedDescriptorList.getUuid(), descriptorList.getUuid());
assertThat(publishedDescriptorList.getFirstPublishedDate(), is(notNullValue()));
}
private DescriptorList setUpDescriptorList(final PublishState state, final UUID uuid, final String description, final String title, final String versionTag)
throws JsonProcessingException {
final DescriptorList o = new DescriptorList();
......
......@@ -788,4 +788,84 @@ public class SubsetRestControllerTest extends AbstractSubsetControllerTest {
assertEquals(true, subsetRepository.getByUuid(publishedSubset_1.getUuid()).getCurrent());
}
@Test
public void firstPublishedDateTest() throws Exception {
// Create new Subset
Subset subset = new Subset();
subset.setWiewsCode(institute.getCode());
subset.setTitle(TITLE);
subset.setState(PublishState.PUBLISHED);
subset.setDescription(DESCRIPTION);
subset.setPublisher(PUBLISHER);
subset.setOwner(owner);
subset.setDateCreated(DATE_CREATED);
subset.setSubsetType(Subset.SubsetType.SELECTIVE);
subset.setSelectionMethod("Tolerance to drought");
final String s = verboseMapper.writeValueAsString(subset);
/*@formatter:off*/
mockMvc
.perform(post(SubsetController.CONTROLLER_URL + "/create")
.contentType(MediaType.APPLICATION_JSON)
.content(s))
// .andDo(org.springframework.test.web.servlet.result.MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(jsonPath("$", not(nullValue())))
.andExpect(jsonPath("$.title", is(TITLE)))
.andExpect(jsonPath("$.description", is(DESCRIPTION)))
.andExpect(jsonPath("$.publisher", is(PUBLISHER)))
.andExpect(jsonPath("$.owner.name", is(owner.getName())))
.andExpect(jsonPath("$.current", is(nullValue())))
.andExpect(jsonPath("$.dateCreated", is(DATE_CREATED)))
.andExpect(jsonPath("$.subsetType", is(Subset.SubsetType.SELECTIVE.name())))
.andExpect(jsonPath("$.selectionMethod", is("Tolerance to drought")))
.andExpect(jsonPath("$.firstPublishedDate", is(nullValue())))
;
/*@formatter:on*/
assertEquals(subsetVersionsRepository.count(), 1);
assertThat(subsetRepository.count(), is(1L));
subset = subsetRepository.findAll().get(0);
assertThat(subset.getFirstPublishedDate(), is(nullValue()));
// Approve Subset
subset = subsetService.reviewSubset(subset);
assertThat(subset.getState(), is(PublishState.REVIEWING));
/*@formatter:off*/
mockMvc
.perform(post(SubsetController.CONTROLLER_URL.concat("/approve"))
.param("uuid", subset.getUuid().toString())
.param("version", subset.getVersion().toString()))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE))
.andExpect(jsonPath("$", not(nullValue())))
.andExpect(jsonPath("$.uuid", is(subset.getUuid().toString())))
.andExpect(jsonPath("$.current", is(Boolean.TRUE)))
.andExpect(jsonPath("$.state", is(PublishState.PUBLISHED.name())));
/*@formatter:on*/
assertEquals(subsetVersionsRepository.count(), 1);
Subset publishedSubset = subsetVersionsRepository.findAll().stream().findFirst().get().getCurrentVersion();
assertEquals(publishedSubset.getUuid(), subset.getUuid());
assertThat(publishedSubset.getFirstPublishedDate(), is(notNullValue()));
// Create new version of Dataset