Skip to content

Commit

Permalink
Merge pull request #484 from SSHOC/develop
Browse files Browse the repository at this point in the history
Push fix for issue 478 to production
  • Loading branch information
KlausIllmayer authored Nov 6, 2024
2 parents ddae557 + e72ac16 commit 3983a16
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 14 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ jobs:
APP_ROOT: ${{ needs.setup_workflow_env.outputs.APP_ROOT }}
SERVICE_ID: ${{ needs.setup_workflow_env.outputs.SERVICE_ID }}
PUBLIC_URL: ${{ needs.setup_workflow_env.outputs.PUBLIC_URL }}
do_not_generate_additional_host_names: "true"
POSTGRES_ENABLED: ${{ needs.setup_workflow_env.outputs.POSTGRES_ENABLED == 'true'}}
default_port: "${{ needs.setup_workflow_env.outputs.default_port}}"
submodules: ${{ needs.setup_workflow_env.outputs.submodules }}
Expand All @@ -131,6 +132,7 @@ jobs:
APP_ROOT: ${{ needs.setup_workflow_env.outputs.APP_ROOT }}
SERVICE_ID: ${{ needs.setup_workflow_env.outputs.SERVICE_ID }}
PUBLIC_URL: ${{ needs.setup_workflow_env.outputs.PUBLIC_URL }}
do_not_generate_additional_host_names: "true"
POSTGRES_ENABLED: ${{ needs.setup_workflow_env.outputs.POSTGRES_ENABLED == 'true'}}
default_port: "${{ needs.setup_workflow_env.outputs.default_port}}"
submodules: ${{ needs.setup_workflow_env.outputs.submodules }}
4 changes: 2 additions & 2 deletions chart/templates/deployment-maketplace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ spec:
path: /api/property-types
port: 8080
scheme: HTTP
initialDelaySeconds: 30
initialDelaySeconds: 90
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 3
Expand All @@ -65,7 +65,7 @@ spec:
path: /api/property-types
port: 8080
scheme: HTTP
initialDelaySeconds: 30
initialDelaySeconds: 90
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 3
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package eu.sshopencloud.marketplace.controllers.sources;

import eu.sshopencloud.marketplace.controllers.PageTooLargeException;
import eu.sshopencloud.marketplace.dto.search.PaginatedSearchItemsBasic;
import eu.sshopencloud.marketplace.dto.items.ItemBasicDto;
import eu.sshopencloud.marketplace.dto.items.PaginatedItemsBasic;
import eu.sshopencloud.marketplace.dto.sources.PaginatedSources;
import eu.sshopencloud.marketplace.dto.sources.SourceCore;
import eu.sshopencloud.marketplace.dto.sources.SourceDto;
Expand Down Expand Up @@ -68,19 +69,19 @@ public void deleteSource(@PathVariable("id") long id) {

@Operation(summary = "Get list of items for given source")
@GetMapping(path = "/{sourceId}/items", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedSearchItemsBasic> getItemsForSource(@PathVariable("sourceId") Long sourceId,
public ResponseEntity<PaginatedItemsBasic<ItemBasicDto>> getItemsForSource(@PathVariable("sourceId") Long sourceId,
@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "perpage", required = false) Integer perpage)
throws PageTooLargeException {
return ResponseEntity.ok(itemService.getItemsBySource(sourceId, pageCoordsValidator.validate(page, perpage)));
return ResponseEntity.ok(itemService.getItemsBySource(sourceId, null, pageCoordsValidator.validate(page, perpage)));
}

@Operation(summary = "Get list of items for given source and id of an item in this source")
@GetMapping(path = "/{sourceId}/items/{sourceItemId}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<PaginatedSearchItemsBasic> getItemsForSourceAndSourceItemId(@PathVariable("sourceId") Long sourceId,
@PathVariable("sourceItemId") String sourceItemId,
@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "perpage", required = false) Integer perpage)
public ResponseEntity<PaginatedItemsBasic<ItemBasicDto>> getItemsForSourceAndSourceItemId(@PathVariable("sourceId") Long sourceId,
@PathVariable("sourceItemId") String sourceItemId,
@RequestParam(value = "page", required = false) Integer page,
@RequestParam(value = "perpage", required = false) Integer perpage)
throws PageTooLargeException {
return ResponseEntity.ok(itemService.getItemsBySource(sourceId, sourceItemId, pageCoordsValidator.validate(page, perpage)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,19 @@ Optional<ZonedDateTime> getMinLastUpdateDateOfActiveItemByStatusAndNotCategory(I
" WHERE i.status = :status AND v.active = true AND v.persistentId = :persistentId AND i.category <> :notCategory")
Optional<Item> findActiveByPersistentIdAndStatusAndCategoryNot(String persistentId, ItemStatus status,
ItemCategory notCategory);

@Query("select i from Item i, VersionedItem v" +
" WHERE i.versionedItem = v AND v.active = true AND i.status=:status AND i.source.id = :sourceId AND (:sourceItemId is null OR i.sourceItemId = :sourceItemId)" +
" ORDER BY i.label, i.id")
Page<Item> getActiveItemsBySourceOrderByLabel(Long sourceId, String sourceItemId, ItemStatus status, Pageable pageable);

@Query("select i from Item i, VersionedItem v" +
" WHERE i.versionedItem = v AND v.active = true AND i.source.id = :sourceId AND (:sourceItemId is null OR i.sourceItemId = :sourceItemId)" +
" ORDER BY i.label, i.id")
Page<Item> getActiveItemsBySourceOrderByLabel(Long sourceId, String sourceItemId, Pageable pageable);

@Query("select i from Item i, VersionedItem v" +
" WHERE i.versionedItem = v AND v.active = true AND (i.status=:status OR i.informationContributor.id = :userId) AND i.source.id = :sourceId AND (:sourceItemId is null OR i.sourceItemId = :sourceItemId)" +
" ORDER BY i.label, i.id")
Page<Item> getActiveOrOwnedItemsBySourceOrderByLabel(Long sourceId, String sourceItemId, ItemStatus status, Long userId, Pageable pageable);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import eu.sshopencloud.marketplace.repositories.sources.SourceRepository;
import eu.sshopencloud.marketplace.services.auth.LoggedInUserHolder;
import eu.sshopencloud.marketplace.services.search.SearchConverter;
import jakarta.persistence.EntityNotFoundException;
import org.apache.commons.lang3.StringUtils;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.response.QueryResponse;
Expand All @@ -27,7 +28,6 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.persistence.EntityNotFoundException;
import java.util.*;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -112,17 +112,51 @@ private Sort.Order getSortOrderByItemOrder(ItemOrder itemOrder, boolean directPr
}


public PaginatedSearchItemsBasic getItemsBySource(Long sourceId, PageCoords pageCoords) {
return getItemsBySource(sourceId, null, pageCoords);
public PaginatedSearchItemsBasic searchItemsBySource(Long sourceId, PageCoords pageCoords) {
return searchItemsBySource(sourceId, null, pageCoords);
}

public PaginatedSearchItemsBasic getItemsBySource(Long sourceId, String sourceItemId, PageCoords pageCoords) {
public PaginatedSearchItemsBasic searchItemsBySource(Long sourceId, String sourceItemId, PageCoords pageCoords) {
Source source = sourceRepository.findById(sourceId)
.orElseThrow(() -> new EntityNotFoundException("Unable to find " + Source.class.getName() + " with id " + sourceId));

return findLatestItemsForSource(source, sourceItemId, pageCoords);
}

public PaginatedItemsBasic<ItemBasicDto> getItemsBySource(Long sourceId, String sourceItemId, PageCoords pageCoords) {
Source source = sourceRepository.findById(sourceId)
.orElseThrow(() -> new EntityNotFoundException("Unable to find " + Source.class.getName() + " with id " + sourceId));

return getItemsBySourceOrderByLabel(source.getId(), sourceItemId, pageCoords);
}

public PaginatedItemsBasic<ItemBasicDto> getItemsBySourceOrderByLabel(Long sourceId, String sourceItemId, PageCoords pageCoords) {
Pageable pageable = PageRequest.of(pageCoords.getPage() - 1, pageCoords.getPerpage()); // DB counts from page 0

Page<Item> itemsPage;
User currentUser = LoggedInUserHolder.getLoggedInUser();
if (currentUser == null || !currentUser.isModerator()) {
if (currentUser == null || !currentUser.isContributor()) {
itemsPage = itemRepository.getActiveItemsBySourceOrderByLabel(sourceId, sourceItemId, ItemStatus.APPROVED, pageable);
}
else {
itemsPage = itemRepository.getActiveOrOwnedItemsBySourceOrderByLabel(sourceId, sourceItemId, ItemStatus.APPROVED, currentUser.getId(), pageable);
}
}
else {
itemsPage = itemRepository.getActiveItemsBySourceOrderByLabel(sourceId, sourceItemId, pageable);
}

return PaginatedItemsBasic.<ItemBasicDto>builder()
.items(itemsPage.stream().map(ItemConverter::convertItem).collect(Collectors.toList()))
.hits(itemsPage.getTotalElements())
.count(itemsPage.getSize())
.page(pageCoords.getPage())
.perpage(pageCoords.getPerpage())
.pages((int) Math.ceil((double)itemsPage.getTotalElements() / (double)pageCoords.getPerpage()))
.build();
}

public PaginatedSearchItemsBasic findLatestItemsForSource(Source source, String sourceItemId, PageCoords pageCoords) {
Pageable pageable = PageRequest.of(pageCoords.getPage() - 1, pageCoords.getPerpage()); // SOLR counts from page 0

Expand All @@ -133,7 +167,7 @@ public PaginatedSearchItemsBasic findLatestItemsForSource(Source source, String
queryBuilder.append(" AND source_item_id:");
queryBuilder.append("\"").append(sourceItemId).append("\"");
}
// Criteria queryCriteria = new SimpleStringCriteria(queryBuilder.toString());

SolrQuery solrQuery = new SolrQuery(queryBuilder.toString());

User currentUser = LoggedInUserHolder.getLoggedInUser();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
package eu.sshopencloud.marketplace.controllers.sources;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import eu.sshopencloud.marketplace.conf.TestJsonMapper;
import eu.sshopencloud.marketplace.conf.auth.LogInTestClient;
import eu.sshopencloud.marketplace.dto.actors.ActorCore;
import eu.sshopencloud.marketplace.dto.actors.ActorId;
import eu.sshopencloud.marketplace.dto.actors.ActorRoleId;
import eu.sshopencloud.marketplace.dto.datasets.DatasetCore;
import eu.sshopencloud.marketplace.dto.datasets.DatasetDto;
import eu.sshopencloud.marketplace.dto.items.ItemContributorId;
import eu.sshopencloud.marketplace.dto.sources.SourceCore;
import eu.sshopencloud.marketplace.dto.sources.SourceDto;
import eu.sshopencloud.marketplace.dto.sources.SourceId;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.MethodOrderer;
Expand All @@ -20,6 +28,10 @@
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
Expand Down Expand Up @@ -281,4 +293,101 @@ public void shouldGetItemsBySourceIdAndSourceItemId() throws Exception {
.andExpect(jsonPath("items[0].label", is("Webinar on DH")));
}

@Test
public void shouldUpdateActorRelatedToItemAngGetThisItem() throws Exception {
Long sourceId = 2L;
String sourceItemId = "rT8gg";
Long actorIdToUpdate = 4L;

// create datasets that relate to the actor we are going to update
ItemContributorId contributor = new ItemContributorId(new ActorId(4L), new ActorRoleId("contributor"));

List<String> datasetsPIDs = new ArrayList<>();

IntStream.range(1, 11).forEach(i -> {
DatasetCore dataset = new DatasetCore();
dataset.setLabel("Test dataset with source and actor " + i);
dataset.setDescription("Lorem ipsum");
SourceId source = new SourceId();
source.setId(sourceId);
dataset.setSource(source);
dataset.setSourceItemId(sourceItemId);
dataset.setContributors(List.of(contributor));

String payload = null;
try {
payload = mapper.writeValueAsString(dataset);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
log.debug("JSON: " + payload);

try {
mvc.perform(post("/api/datasets")
.content(payload)
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", MODERATOR_JWT))
.andExpect(status().isOk())
.andExpect(jsonPath("status", is("approved")))
.andExpect(jsonPath("category", is("dataset")))
.andExpect(jsonPath("label", is("Test dataset with source and actor " + i)))
.andExpect(jsonPath("description", is("Lorem ipsum")))
.andExpect(jsonPath("properties", hasSize(0)))
.andExpect(jsonPath("source.id", is(2)))
.andExpect(jsonPath("source.label", is("Programming Historian")))
.andExpect(jsonPath("source.url", is("https://programminghistorian.org")))
.andExpect(jsonPath("sourceItemId", is("rT8gg"))).andDo(h -> {
datasetsPIDs.add(mapper.readValue(h.getResponse().getContentAsString(), DatasetDto.class).getPersistentId());
});
} catch (Exception e) {
throw new RuntimeException(e);
}
});

ActorCore actor = new ActorCore();
actor.setName("Test actor");
actor.setEmail("[email protected]");
List<ActorId> affiliations = new ArrayList<>();
ActorId affiliation1 = new ActorId();
affiliation1.setId(1L);
affiliations.add(affiliation1);
actor.setAffiliations(affiliations);

String payload = TestJsonMapper.serializingObjectMapper().writeValueAsString(actor);
log.debug("JSON: " + payload);

mvc.perform(put("/api/actors/{id}", actorIdToUpdate)
.content(payload)
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", MODERATOR_JWT))
.andExpect(status().isOk())
.andExpect(jsonPath("name", is("Test actor")))
.andExpect(jsonPath("email", is("[email protected]")))
.andExpect(jsonPath("affiliations", hasSize(1)))
.andExpect(jsonPath("affiliations[0].name", is("Austrian Academy of Sciences")));

mvc.perform(get("/api/sources/{sourceId}/items/{sourceItemId}", sourceId, sourceItemId)
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", ADMINISTRATOR_JWT))
.andExpect(jsonPath("items", hasSize(11)))
.andExpect(jsonPath("items[0].persistentId", is(datasetsPIDs.getFirst())))
.andExpect(jsonPath("items[0].category", is("dataset")))
.andExpect(jsonPath("items[0].label", is("Test dataset with source and actor 1")));

mvc.perform(get("/api/sources/{sourceId}/items/{sourceItemId}", sourceId, sourceItemId)
.contentType(MediaType.APPLICATION_JSON)
.header("Authorization", CONTRIBUTOR_JWT))
.andExpect(jsonPath("items", hasSize(11)))
.andExpect(jsonPath("items[0].persistentId", is(datasetsPIDs.getFirst())))
.andExpect(jsonPath("items[0].category", is("dataset")))
.andExpect(jsonPath("items[0].label", is("Test dataset with source and actor 1")));

mvc.perform(get("/api/sources/{sourceId}/items/{sourceItemId}", sourceId, sourceItemId)
.contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("items", hasSize(11)))
.andExpect(jsonPath("items[0].persistentId", is(datasetsPIDs.getFirst())))
.andExpect(jsonPath("items[0].category", is("dataset")))
.andExpect(jsonPath("items[0].label", is("Test dataset with source and actor 1")));
}

}

0 comments on commit 3983a16

Please sign in to comment.