diff --git a/src/main/java/nl/dtls/fairdatapoint/api/controller/index/IndexAdminController.java b/src/main/java/nl/dtls/fairdatapoint/api/controller/index/IndexAdminController.java index 1880baca5..7f71acca9 100644 --- a/src/main/java/nl/dtls/fairdatapoint/api/controller/index/IndexAdminController.java +++ b/src/main/java/nl/dtls/fairdatapoint/api/controller/index/IndexAdminController.java @@ -31,8 +31,8 @@ import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.entity.index.event.Event; import nl.dtls.fairdatapoint.service.UtilityService; +import nl.dtls.fairdatapoint.service.index.entry.IndexEntryService; import nl.dtls.fairdatapoint.service.index.event.EventService; -import nl.dtls.fairdatapoint.service.index.harvester.HarvesterService; import nl.dtls.fairdatapoint.service.index.webhook.WebhookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -57,7 +57,7 @@ public class IndexAdminController { private WebhookService webhookService; @Autowired - private HarvesterService harvesterService; + private IndexEntryService indexEntryService; @Operation(hidden = true) @PostMapping("/trigger") @@ -72,7 +72,7 @@ public void triggerMetadataRetrieve( final Event event = eventService.acceptAdminTrigger(request, reqDto); webhookService.triggerWebhooks(event); eventService.triggerMetadataRetrieval(event); - harvesterService.harvest(reqDto.getClientUrl()); + indexEntryService.harvest(reqDto.getClientUrl()); } @Operation(hidden = true) diff --git a/src/main/java/nl/dtls/fairdatapoint/api/controller/index/IndexEntryController.java b/src/main/java/nl/dtls/fairdatapoint/api/controller/index/IndexEntryController.java index e836e0d52..ff5d8f510 100644 --- a/src/main/java/nl/dtls/fairdatapoint/api/controller/index/IndexEntryController.java +++ b/src/main/java/nl/dtls/fairdatapoint/api/controller/index/IndexEntryController.java @@ -23,17 +23,26 @@ package nl.dtls.fairdatapoint.api.controller.index; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; import nl.dtls.fairdatapoint.api.dto.index.entry.IndexEntryDTO; import nl.dtls.fairdatapoint.api.dto.index.entry.IndexEntryDetailDTO; import nl.dtls.fairdatapoint.api.dto.index.entry.IndexEntryInfoDTO; +import nl.dtls.fairdatapoint.api.dto.index.entry.IndexEntryUpdateDTO; +import nl.dtls.fairdatapoint.api.dto.index.ping.PingDTO; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; +import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryPermit; +import nl.dtls.fairdatapoint.entity.index.event.Event; import nl.dtls.fairdatapoint.service.index.entry.IndexEntryService; +import nl.dtls.fairdatapoint.service.index.event.EventService; +import nl.dtls.fairdatapoint.service.index.harvester.HarvesterService; +import nl.dtls.fairdatapoint.service.index.webhook.WebhookService; import org.eclipse.rdf4j.model.Model; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -47,12 +56,25 @@ public class IndexEntryController { @Autowired private IndexEntryService service; + @Autowired + private HarvesterService harvesterService; + + @Autowired + private EventService eventService; + + @Autowired + private WebhookService webhookService; + + @Autowired + private IndexEntryService indexEntryService; + @GetMapping(path = "", produces = MediaType.APPLICATION_JSON_VALUE) public Page getEntriesPage( Pageable pageable, - @RequestParam(required = false, defaultValue = "") String state + @RequestParam(required = false, defaultValue = "") String state, + @RequestParam(required = false, defaultValue = "accepted") String permit ) { - return service.getEntriesPageDTOs(pageable, state); + return service.getEntriesPageDTOs(pageable, state, permit); } @GetMapping(path = "/{uuid}", produces = MediaType.APPLICATION_JSON_VALUE) @@ -60,6 +82,29 @@ public Optional getEntry(@PathVariable final String uuid) { return service.getEntryDetailDTO(uuid); } + @PutMapping(path = "/{uuid}", produces = MediaType.APPLICATION_JSON_VALUE) + @PreAuthorize("hasRole('ADMIN')") + public Optional updateEntry( + @PathVariable final String uuid, + @RequestBody IndexEntryUpdateDTO reqDto, + HttpServletRequest request + ) throws MetadataRepositoryException { + final Optional resDto = service.updateEntry(uuid, reqDto); + if (resDto.isPresent()) { + final String clientUrl = resDto.get().getClientUrl(); + if (resDto.get().getPermit().equals(IndexEntryPermit.ACCEPTED)) { + final Event event = eventService.acceptAdminTrigger(request, new PingDTO(clientUrl)); + webhookService.triggerWebhooks(event); + eventService.triggerMetadataRetrieval(event); + indexEntryService.harvest(clientUrl); + } + else { + harvesterService.deleteHarvestedData(clientUrl); + } + } + return resDto; + } + @GetMapping(path = "/{uuid}/data", produces = "!application/json") public Model getEntryData(@PathVariable final String uuid) throws MetadataRepositoryException { return service.getEntryHarvestedData(uuid); @@ -72,12 +117,16 @@ public void deleteEntry(@PathVariable final String uuid) throws MetadataReposito } @GetMapping(path = "/all", produces = MediaType.APPLICATION_JSON_VALUE) - public List getEntriesAll() { - return service.getAllEntriesAsDTOs(); + public List getEntriesAll( + @RequestParam(required = false, defaultValue = "accepted") String permit + ) { + return service.getAllEntriesAsDTOs(permit); } @GetMapping(path = "/info", produces = MediaType.APPLICATION_JSON_VALUE) - public IndexEntryInfoDTO getEntriesInfo() { - return service.getEntriesInfo(); + public IndexEntryInfoDTO getEntriesInfo( + @RequestParam(required = false, defaultValue = "accepted") String permit + ) { + return service.getEntriesInfo(permit); } } diff --git a/src/main/java/nl/dtls/fairdatapoint/api/controller/index/IndexPingController.java b/src/main/java/nl/dtls/fairdatapoint/api/controller/index/IndexPingController.java index ddf45d92c..2030845df 100644 --- a/src/main/java/nl/dtls/fairdatapoint/api/controller/index/IndexPingController.java +++ b/src/main/java/nl/dtls/fairdatapoint/api/controller/index/IndexPingController.java @@ -35,8 +35,8 @@ import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.entity.index.event.Event; import nl.dtls.fairdatapoint.service.UtilityService; +import nl.dtls.fairdatapoint.service.index.entry.IndexEntryService; import nl.dtls.fairdatapoint.service.index.event.EventService; -import nl.dtls.fairdatapoint.service.index.harvester.HarvesterService; import nl.dtls.fairdatapoint.service.index.webhook.WebhookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -57,7 +57,7 @@ public class IndexPingController { private WebhookService webhookService; @Autowired - private HarvesterService harvesterService; + private IndexEntryService indexEntryService; @Autowired private UtilityService utilityService; @@ -100,7 +100,7 @@ public ResponseEntity receivePing( final Event event = eventService.acceptIncomingPing(reqDto, request); log.info("Triggering metadata retrieval for {}", event.getRelatedTo().getClientUrl()); eventService.triggerMetadataRetrieval(event); - harvesterService.harvest(reqDto.getClientUrl()); + indexEntryService.harvest(reqDto.getClientUrl()); webhookService.triggerWebhooks(event); return new ResponseEntity<>(HttpStatus.NO_CONTENT); } diff --git a/src/main/java/nl/dtls/fairdatapoint/api/dto/index/entry/IndexEntryDTO.java b/src/main/java/nl/dtls/fairdatapoint/api/dto/index/entry/IndexEntryDTO.java index b76213859..ba6c9dac7 100644 --- a/src/main/java/nl/dtls/fairdatapoint/api/dto/index/entry/IndexEntryDTO.java +++ b/src/main/java/nl/dtls/fairdatapoint/api/dto/index/entry/IndexEntryDTO.java @@ -27,6 +27,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryPermit; import org.hibernate.validator.constraints.URL; @NoArgsConstructor @@ -45,6 +46,9 @@ public class IndexEntryDTO { @NotNull private IndexEntryStateDTO state; + @NotNull + private IndexEntryPermit permit; + @NotNull private String registrationTime; diff --git a/src/main/java/nl/dtls/fairdatapoint/api/dto/index/entry/IndexEntryDetailDTO.java b/src/main/java/nl/dtls/fairdatapoint/api/dto/index/entry/IndexEntryDetailDTO.java index b821a86e0..67bf2865c 100644 --- a/src/main/java/nl/dtls/fairdatapoint/api/dto/index/entry/IndexEntryDetailDTO.java +++ b/src/main/java/nl/dtls/fairdatapoint/api/dto/index/entry/IndexEntryDetailDTO.java @@ -28,6 +28,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import nl.dtls.fairdatapoint.api.dto.index.event.EventDTO; +import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryPermit; import nl.dtls.fairdatapoint.entity.index.entry.RepositoryMetadata; import org.hibernate.validator.constraints.URL; @@ -49,6 +50,9 @@ public class IndexEntryDetailDTO { @NotNull private IndexEntryStateDTO state; + @NotNull + private IndexEntryPermit permit; + @NotNull private RepositoryMetadata currentMetadata; diff --git a/src/main/java/nl/dtls/fairdatapoint/api/dto/index/entry/IndexEntryUpdateDTO.java b/src/main/java/nl/dtls/fairdatapoint/api/dto/index/entry/IndexEntryUpdateDTO.java new file mode 100644 index 000000000..8543a302c --- /dev/null +++ b/src/main/java/nl/dtls/fairdatapoint/api/dto/index/entry/IndexEntryUpdateDTO.java @@ -0,0 +1,38 @@ +/** + * The MIT License + * Copyright © 2017 DTL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package nl.dtls.fairdatapoint.api.dto.index.entry; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryPermit; + +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class IndexEntryUpdateDTO { + + private IndexEntryPermit permit; +} diff --git a/src/main/java/nl/dtls/fairdatapoint/api/dto/index/settings/IndexSettingsDTO.java b/src/main/java/nl/dtls/fairdatapoint/api/dto/index/settings/IndexSettingsDTO.java index 2f1ae628d..db47118f8 100644 --- a/src/main/java/nl/dtls/fairdatapoint/api/dto/index/settings/IndexSettingsDTO.java +++ b/src/main/java/nl/dtls/fairdatapoint/api/dto/index/settings/IndexSettingsDTO.java @@ -39,6 +39,9 @@ public class IndexSettingsDTO { @NotNull private IndexSettingsPingDTO ping; + @NotNull + private Boolean autoPermit; + @NotNull private Boolean isDefault; } diff --git a/src/main/java/nl/dtls/fairdatapoint/api/dto/index/settings/IndexSettingsUpdateDTO.java b/src/main/java/nl/dtls/fairdatapoint/api/dto/index/settings/IndexSettingsUpdateDTO.java index ccd3011b8..cce001e42 100644 --- a/src/main/java/nl/dtls/fairdatapoint/api/dto/index/settings/IndexSettingsUpdateDTO.java +++ b/src/main/java/nl/dtls/fairdatapoint/api/dto/index/settings/IndexSettingsUpdateDTO.java @@ -41,4 +41,7 @@ public class IndexSettingsUpdateDTO { @Valid @NotNull private IndexSettingsPingDTO ping; + + @NotNull + private Boolean autoPermit; } diff --git a/src/main/java/nl/dtls/fairdatapoint/config/properties/InstanceProperties.java b/src/main/java/nl/dtls/fairdatapoint/config/properties/InstanceProperties.java index 28e7aff37..90fb4ae58 100644 --- a/src/main/java/nl/dtls/fairdatapoint/config/properties/InstanceProperties.java +++ b/src/main/java/nl/dtls/fairdatapoint/config/properties/InstanceProperties.java @@ -38,6 +38,7 @@ public class InstanceProperties { private boolean behindProxy = true; private String persistentUrl; private boolean index; + private boolean indexAutoPermit; private String title = "FAIR Data Point"; private String subtitle = "Metadata for machines"; diff --git a/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/index/entry/data/IndexEntryFixtures.java b/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/index/entry/data/IndexEntryFixtures.java index a0912576a..7b231334e 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/index/entry/data/IndexEntryFixtures.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/development/index/entry/data/IndexEntryFixtures.java @@ -23,14 +23,14 @@ package nl.dtls.fairdatapoint.database.mongo.migration.development.index.entry.data; import nl.dtls.fairdatapoint.entity.index.entry.IndexEntry; +import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryPermit; +import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryState; import nl.dtls.fairdatapoint.entity.index.entry.RepositoryMetadata; import org.springframework.stereotype.Service; import java.time.Instant; import java.util.HashMap; -import static nl.dtls.fairdatapoint.entity.index.entry.IndexEntryState.*; - @Service public class IndexEntryFixtures { @@ -41,10 +41,16 @@ public IndexEntry entryActive() { clientUri, new HashMap<>() ); - return new IndexEntry( - "8987abc1-15a4-4752-903c-8f8a5882cca6", clientUri, - Valid, Instant.now(), Instant.now(), Instant.now(), repositoryData - ); + return IndexEntry.builder() + .uuid("8987abc1-15a4-4752-903c-8f8a5882cca6") + .clientUrl(clientUri) + .state(IndexEntryState.Valid) + .permit(IndexEntryPermit.ACCEPTED) + .registrationTime(Instant.now()) + .modificationTime(Instant.now()) + .lastRetrievalTime(Instant.now()) + .currentMetadata(repositoryData) + .build(); } public IndexEntry entryActive2() { @@ -55,10 +61,16 @@ public IndexEntry entryActive2() { new HashMap<>() ); final Instant date = Instant.parse("2020-05-30T23:38:31.085Z"); - return new IndexEntry( - "c912331f-4a77-4300-a469-dbaf5fc0b4e2", clientUri, - Valid, date, date, date, repositoryData - ); + return IndexEntry.builder() + .uuid("c912331f-4a77-4300-a469-dbaf5fc0b4e2") + .clientUrl(clientUri) + .state(IndexEntryState.Valid) + .permit(IndexEntryPermit.ACCEPTED) + .registrationTime(date) + .modificationTime(date) + .lastRetrievalTime(date) + .currentMetadata(repositoryData) + .build(); } public IndexEntry entryInactive() { @@ -69,9 +81,16 @@ public IndexEntry entryInactive() { new HashMap<>() ); final Instant date = Instant.parse("2020-05-30T23:38:23.085Z"); - return new IndexEntry("b5851ebe-aacf-4de9-bf0a-3686e9256e73", clientUri, - Valid, date, date, date, repositoryData - ); + return IndexEntry.builder() + .uuid("b5851ebe-aacf-4de9-bf0a-3686e9256e73") + .clientUrl(clientUri) + .state(IndexEntryState.Valid) + .permit(IndexEntryPermit.ACCEPTED) + .registrationTime(date) + .modificationTime(date) + .lastRetrievalTime(date) + .currentMetadata(repositoryData) + .build(); } public IndexEntry entryUnreachable() { @@ -81,10 +100,16 @@ public IndexEntry entryUnreachable() { clientUri, new HashMap<>() ); - return new IndexEntry( - "dae46b47-87fb-4fdf-995c-8aa3739a27fc", clientUri, - Unreachable, Instant.now(), Instant.now(), Instant.now(), repositoryData - ); + return IndexEntry.builder() + .uuid("dae46b47-87fb-4fdf-995c-8aa3739a27fc") + .clientUrl(clientUri) + .state(IndexEntryState.Unreachable) + .permit(IndexEntryPermit.ACCEPTED) + .registrationTime(Instant.now()) + .modificationTime(Instant.now()) + .lastRetrievalTime(Instant.now()) + .currentMetadata(repositoryData) + .build(); } public IndexEntry entryInvalid() { @@ -94,10 +119,16 @@ public IndexEntry entryInvalid() { clientUri, new HashMap<>() ); - return new IndexEntry( - "b37e8c1f-ac0e-49f8-8e07-35571c4f8235", clientUri, - Invalid, Instant.now(), Instant.now(), Instant.now(), repositoryData - ); + return IndexEntry.builder() + .uuid("b37e8c1f-ac0e-49f8-8e07-35571c4f8235") + .clientUrl(clientUri) + .state(IndexEntryState.Invalid) + .permit(IndexEntryPermit.ACCEPTED) + .registrationTime(Instant.now()) + .modificationTime(Instant.now()) + .lastRetrievalTime(Instant.now()) + .currentMetadata(repositoryData) + .build(); } public IndexEntry entryUnknown() { @@ -107,10 +138,54 @@ public IndexEntry entryUnknown() { clientUri, new HashMap<>() ); - return new IndexEntry( - "4471d7c5-8c5b-4581-a9bc-d175456492c4", clientUri, - Unknown, Instant.now(), Instant.now(), Instant.now(), repositoryData + return IndexEntry.builder() + .uuid("4471d7c5-8c5b-4581-a9bc-d175456492c4") + .clientUrl(clientUri) + .state(IndexEntryState.Unknown) + .permit(IndexEntryPermit.ACCEPTED) + .registrationTime(Instant.now()) + .modificationTime(Instant.now()) + .lastRetrievalTime(Instant.now()) + .currentMetadata(repositoryData) + .build(); + } + + public IndexEntry entryRejected() { + final String clientUri = "https://example.com/valid-rejected-fairdatapoint"; + final RepositoryMetadata repositoryData = new RepositoryMetadata( + RepositoryMetadata.CURRENT_VERSION, + clientUri, + new HashMap<>() + ); + return IndexEntry.builder() + .uuid("4471d7c5-8c5b-4581-a9bc-d175456492c5") + .clientUrl(clientUri) + .state(IndexEntryState.Valid) + .permit(IndexEntryPermit.REJECTED) + .registrationTime(Instant.now()) + .modificationTime(Instant.now()) + .lastRetrievalTime(Instant.now()) + .currentMetadata(repositoryData) + .build(); + } + + public IndexEntry entryPending() { + final String clientUri = "https://example.com/valid-pending-fairdatapoint"; + final RepositoryMetadata repositoryData = new RepositoryMetadata( + RepositoryMetadata.CURRENT_VERSION, + clientUri, + new HashMap<>() ); + return IndexEntry.builder() + .uuid("4471d7c5-8c5b-4581-a9bc-d175456492c6") + .clientUrl(clientUri) + .state(IndexEntryState.Valid) + .permit(IndexEntryPermit.PENDING) + .registrationTime(Instant.now()) + .modificationTime(Instant.now()) + .lastRetrievalTime(Instant.now()) + .currentMetadata(repositoryData) + .build(); } } diff --git a/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/production/Migration_0016_IndexSettingsAutoPermit.java b/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/production/Migration_0016_IndexSettingsAutoPermit.java new file mode 100644 index 000000000..363ab3eb8 --- /dev/null +++ b/src/main/java/nl/dtls/fairdatapoint/database/mongo/migration/production/Migration_0016_IndexSettingsAutoPermit.java @@ -0,0 +1,70 @@ +/** + * The MIT License + * Copyright © 2017 DTL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package nl.dtls.fairdatapoint.database.mongo.migration.production; + +import com.mongodb.client.MongoCollection; +import com.mongodb.client.model.Filters; +import com.mongodb.client.model.Updates; +import io.mongock.api.annotations.ChangeUnit; +import io.mongock.api.annotations.Execution; +import io.mongock.api.annotations.RollbackExecution; +import nl.dtls.fairdatapoint.Profiles; +import org.bson.Document; +import org.springframework.context.annotation.Profile; +import org.springframework.data.mongodb.core.MongoTemplate; + +@ChangeUnit( + id = "Migration_0016_IndexSettingsAutoPermit", + order = "0016", + author = "migrationBot" +) +@Profile(Profiles.PRODUCTION) +public class Migration_0016_IndexSettingsAutoPermit { + + private static final String FIELD_AUTO_PERMIT = "autoPermit"; + private static final String COL_INDEX_SETTINGS = "indexSettings"; + + private final MongoTemplate database; + + public Migration_0016_IndexSettingsAutoPermit(MongoTemplate template) { + this.database = template; + } + + @Execution + public void run() { + final MongoCollection settingsCol = database.getCollection(COL_INDEX_SETTINGS); + settingsCol.updateMany( + Filters.not(Filters.exists(FIELD_AUTO_PERMIT)), + Updates.set(FIELD_AUTO_PERMIT, true) + ); + } + + @RollbackExecution + public void rollback() { + final MongoCollection settingsCol = database.getCollection(COL_INDEX_SETTINGS); + settingsCol.updateMany( + Filters.exists(FIELD_AUTO_PERMIT), + Updates.unset(FIELD_AUTO_PERMIT) + ); + } +} diff --git a/src/main/java/nl/dtls/fairdatapoint/database/mongo/repository/IndexEntryRepository.java b/src/main/java/nl/dtls/fairdatapoint/database/mongo/repository/IndexEntryRepository.java index 3866e4ab0..905acc1be 100644 --- a/src/main/java/nl/dtls/fairdatapoint/database/mongo/repository/IndexEntryRepository.java +++ b/src/main/java/nl/dtls/fairdatapoint/database/mongo/repository/IndexEntryRepository.java @@ -23,12 +23,14 @@ package nl.dtls.fairdatapoint.database.mongo.repository; import nl.dtls.fairdatapoint.entity.index.entry.IndexEntry; +import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryPermit; import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryState; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.mongodb.repository.MongoRepository; import java.time.Instant; +import java.util.List; import java.util.Optional; public interface IndexEntryRepository extends MongoRepository { @@ -37,18 +39,30 @@ public interface IndexEntryRepository extends MongoRepository findByClientUrl(String clientUrl); - Page findAllByStateEquals(Pageable pageable, IndexEntryState state); + Page findAllByStateEqualsAndPermitIn( + Pageable pageable, IndexEntryState state, List permit + ); - Page findAllByStateEqualsAndLastRetrievalTimeBefore(Pageable pageable, IndexEntryState state, - Instant when); + Page findAllByStateEqualsAndLastRetrievalTimeBeforeAndPermitIn( + Pageable pageable, IndexEntryState state, Instant when, List permit + ); - Page findAllByStateEqualsAndLastRetrievalTimeAfter(Pageable pageable, IndexEntryState state, - Instant when); + Page findAllByStateEqualsAndLastRetrievalTimeAfterAndPermitIn( + Pageable pageable, IndexEntryState state, Instant when, List permit + ); - long countAllByStateEquals(IndexEntryState state); + Page findAllByPermitIn(Pageable pageable, List permit); - long countAllByStateEqualsAndLastRetrievalTimeAfter(IndexEntryState state, Instant when); + Iterable findAllByPermitIn(List permit); - long countAllByStateEqualsAndLastRetrievalTimeBefore(IndexEntryState state, Instant when); + long countAllByPermitIn(List permit); + long countAllByStateEqualsAndPermitIn(IndexEntryState state, List permit); + + long countAllByStateEqualsAndLastRetrievalTimeAfterAndPermitIn( + IndexEntryState state, Instant when, List permit); + + long countAllByStateEqualsAndLastRetrievalTimeBeforeAndPermitIn( + IndexEntryState state, Instant when, List permit + ); } diff --git a/src/main/java/nl/dtls/fairdatapoint/entity/index/entry/IndexEntry.java b/src/main/java/nl/dtls/fairdatapoint/entity/index/entry/IndexEntry.java index 9c8a59afb..18afbadcb 100644 --- a/src/main/java/nl/dtls/fairdatapoint/entity/index/entry/IndexEntry.java +++ b/src/main/java/nl/dtls/fairdatapoint/entity/index/entry/IndexEntry.java @@ -37,6 +37,7 @@ @Getter @Setter @EqualsAndHashCode +@Builder public class IndexEntry { @Id @@ -48,6 +49,8 @@ public class IndexEntry { private IndexEntryState state = IndexEntryState.Unknown; + private IndexEntryPermit permit = IndexEntryPermit.PENDING; + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) private Instant registrationTime; @@ -59,17 +62,6 @@ public class IndexEntry { private RepositoryMetadata currentMetadata; - public IndexEntry(String uuid, String clientUrl, IndexEntryState state, Instant registrationTime, - Instant modificationTime, Instant lastRetrievalTime, RepositoryMetadata currentMetadata) { - this.uuid = uuid; - this.clientUrl = clientUrl; - this.state = state; - this.registrationTime = registrationTime; - this.modificationTime = modificationTime; - this.lastRetrievalTime = lastRetrievalTime; - this.currentMetadata = currentMetadata; - } - public Duration getLastRetrievalAgo() { if (lastRetrievalTime == null) { return null; diff --git a/src/main/java/nl/dtls/fairdatapoint/entity/index/entry/IndexEntryPermit.java b/src/main/java/nl/dtls/fairdatapoint/entity/index/entry/IndexEntryPermit.java new file mode 100644 index 000000000..c28a1c3c7 --- /dev/null +++ b/src/main/java/nl/dtls/fairdatapoint/entity/index/entry/IndexEntryPermit.java @@ -0,0 +1,29 @@ +/** + * The MIT License + * Copyright © 2017 DTL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package nl.dtls.fairdatapoint.entity.index.entry; + +public enum IndexEntryPermit { + PENDING, + ACCEPTED, + REJECTED, +} diff --git a/src/main/java/nl/dtls/fairdatapoint/entity/index/settings/IndexSettings.java b/src/main/java/nl/dtls/fairdatapoint/entity/index/settings/IndexSettings.java index ca4a05c5c..ade210709 100644 --- a/src/main/java/nl/dtls/fairdatapoint/entity/index/settings/IndexSettings.java +++ b/src/main/java/nl/dtls/fairdatapoint/entity/index/settings/IndexSettings.java @@ -46,12 +46,8 @@ public class IndexSettings { @NotNull private IndexSettingsPing ping; - public static IndexSettings getDefault() { - final IndexSettings settings = new IndexSettings(); - settings.setPing(IndexSettingsPing.getDefault()); - settings.setRetrieval(IndexSettingsRetrieval.getDefault()); - return settings; - } + @NotNull + private Boolean autoPermit; @Override public boolean equals(Object o) { diff --git a/src/main/java/nl/dtls/fairdatapoint/entity/user/User.java b/src/main/java/nl/dtls/fairdatapoint/entity/user/User.java index 7f1ba3386..7a4f4b958 100644 --- a/src/main/java/nl/dtls/fairdatapoint/entity/user/User.java +++ b/src/main/java/nl/dtls/fairdatapoint/entity/user/User.java @@ -61,4 +61,8 @@ public User( this.passwordHash = passwordHash; this.role = role; } + + public boolean isAdmin() { + return role.equals(UserRole.ADMIN); + } } diff --git a/src/main/java/nl/dtls/fairdatapoint/service/index/entry/IndexEntryMapper.java b/src/main/java/nl/dtls/fairdatapoint/service/index/entry/IndexEntryMapper.java index 5fee93392..4a290519a 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/index/entry/IndexEntryMapper.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/index/entry/IndexEntryMapper.java @@ -33,7 +33,6 @@ import org.springframework.stereotype.Service; import java.time.Instant; -import java.util.stream.Collectors; import java.util.stream.StreamSupport; @Service @@ -49,6 +48,7 @@ public IndexEntryDTO toDTO(IndexEntry indexEntry, Instant validThreshold) { toStateDTO(indexEntry.getState(), indexEntry.getLastRetrievalTime(), validThreshold), + indexEntry.getPermit(), indexEntry.getRegistrationTime().toString(), indexEntry.getModificationTime().toString() ); @@ -63,10 +63,11 @@ public IndexEntryDetailDTO toDetailDTO( toStateDTO(indexEntry.getState(), indexEntry.getLastRetrievalTime(), validThreshold), + indexEntry.getPermit(), indexEntry.getCurrentMetadata(), StreamSupport.stream(events.spliterator(), false) .map(eventMapper::toDTO) - .collect(Collectors.toList()), + .toList(), indexEntry.getRegistrationTime().toString(), indexEntry.getModificationTime().toString(), indexEntry.getLastRetrievalTime().toString() diff --git a/src/main/java/nl/dtls/fairdatapoint/service/index/entry/IndexEntryService.java b/src/main/java/nl/dtls/fairdatapoint/service/index/entry/IndexEntryService.java index dc6787bdd..0b0d61046 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/index/entry/IndexEntryService.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/index/entry/IndexEntryService.java @@ -24,32 +24,34 @@ import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; -import nl.dtls.fairdatapoint.api.dto.index.entry.IndexEntryDTO; -import nl.dtls.fairdatapoint.api.dto.index.entry.IndexEntryDetailDTO; -import nl.dtls.fairdatapoint.api.dto.index.entry.IndexEntryInfoDTO; -import nl.dtls.fairdatapoint.api.dto.index.entry.IndexEntryStateDTO; +import nl.dtls.fairdatapoint.api.dto.index.entry.*; import nl.dtls.fairdatapoint.api.dto.index.ping.PingDTO; import nl.dtls.fairdatapoint.database.mongo.repository.IndexEntryRepository; import nl.dtls.fairdatapoint.database.rdf.repository.exception.MetadataRepositoryException; import nl.dtls.fairdatapoint.database.rdf.repository.generic.GenericMetadataRepository; import nl.dtls.fairdatapoint.entity.exception.ResourceNotFoundException; import nl.dtls.fairdatapoint.entity.index.entry.IndexEntry; +import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryPermit; import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryState; +import nl.dtls.fairdatapoint.entity.index.settings.IndexSettings; import nl.dtls.fairdatapoint.service.index.common.RequiredEnabledIndexFeature; import nl.dtls.fairdatapoint.service.index.event.EventService; import nl.dtls.fairdatapoint.service.index.harvester.HarvesterService; import nl.dtls.fairdatapoint.service.index.settings.IndexSettingsService; +import nl.dtls.fairdatapoint.service.user.CurrentUserService; import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.model.impl.TreeModel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import org.springframework.scheduling.annotation.Async; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; import java.time.Instant; import java.util.*; +import java.util.stream.Collectors; import java.util.stream.StreamSupport; import static nl.dtls.fairdatapoint.api.dto.index.entry.IndexEntryStateDTO.*; @@ -62,6 +64,8 @@ public class IndexEntryService { private static final String MSG_NOT_FOUND = "Index entry not found"; + private static final String FILTER_ALL = "ALL"; + @Autowired private IndexEntryRepository repository; @@ -80,47 +84,88 @@ public class IndexEntryService { @Autowired private HarvesterService harvesterService; + @Autowired + private CurrentUserService currentUserService; + @RequiredEnabledIndexFeature public Iterable getAllEntries() { return repository.findAll(); } @RequiredEnabledIndexFeature - public List getAllEntriesAsDTOs() { + public Iterable getAllEntries(String permitQuery) { + final List permit = getPermits(permitQuery); + return repository.findAllByPermitIn(permit); + } + + @RequiredEnabledIndexFeature + public List getAllEntriesAsDTOs(String permitQuery) { final Instant validThreshold = getValidThreshold(); return StreamSupport - .stream(getAllEntries().spliterator(), true) + .stream(getAllEntries(permitQuery).spliterator(), true) .map(entry -> mapper.toDTO(entry, validThreshold)) .toList(); } @RequiredEnabledIndexFeature - public Page getEntriesPage(Pageable pageable, String state) { + public Page getEntriesPage(Pageable pageable, String state, String permitQuery) { + return getEntriesPageWithPermits(pageable, state, getPermits(permitQuery)); + } + + private List getPermits(String permitQuery) { + if (currentUserService.getCurrentUser().isEmpty() + || !currentUserService.getCurrentUser().get().isAdmin()) { + // not admin -> can use just ACCEPTED entries + return List.of(IndexEntryPermit.ACCEPTED); + } + final Set permitStrings = Arrays + .stream(permitQuery.split(",")) + .map(String::toUpperCase) + .collect(Collectors.toSet()); + if (permitStrings.contains(FILTER_ALL)) { + return Arrays.stream(IndexEntryPermit.values()).toList(); + } + return Arrays + .stream(IndexEntryPermit.values()) + .filter(permitValue -> permitStrings.contains(permitValue.name())) + .toList(); + } + + private Page getEntriesPageWithPermits(Pageable pageable, String state, + List permit) { final Instant validThreshold = getValidThreshold(); if (state.equalsIgnoreCase(ACTIVE.name())) { - return repository.findAllByStateEqualsAndLastRetrievalTimeAfter(pageable, - IndexEntryState.Valid, validThreshold); + return repository.findAllByStateEqualsAndLastRetrievalTimeAfterAndPermitIn( + pageable, IndexEntryState.Valid, validThreshold, permit + ); } if (state.equalsIgnoreCase(IndexEntryStateDTO.INACTIVE.name())) { - return repository.findAllByStateEqualsAndLastRetrievalTimeBefore(pageable, - IndexEntryState.Valid, validThreshold); + return repository.findAllByStateEqualsAndLastRetrievalTimeBeforeAndPermitIn( + pageable, IndexEntryState.Valid, validThreshold, permit + ); } if (state.equalsIgnoreCase(IndexEntryStateDTO.UNREACHABLE.name())) { - return repository.findAllByStateEquals(pageable, IndexEntryState.Unreachable); + return repository.findAllByStateEqualsAndPermitIn( + pageable, IndexEntryState.Unreachable, permit + ); } if (state.equalsIgnoreCase(IndexEntryStateDTO.INVALID.name())) { - return repository.findAllByStateEquals(pageable, IndexEntryState.Invalid); + return repository.findAllByStateEqualsAndPermitIn( + pageable, IndexEntryState.Invalid, permit + ); } if (state.equalsIgnoreCase(IndexEntryStateDTO.UNKNOWN.name())) { - return repository.findAllByStateEquals(pageable, IndexEntryState.Unknown); + return repository.findAllByStateEqualsAndPermitIn( + pageable, IndexEntryState.Unknown, permit + ); } - return repository.findAll(pageable); + return repository.findAllByPermitIn(pageable, permit); } @RequiredEnabledIndexFeature - public Page getEntriesPageDTOs(Pageable pageable, String state) { + public Page getEntriesPageDTOs(Pageable pageable, String state, String permitQuery) { final Instant validThreshold = getValidThreshold(); - return getEntriesPage(pageable, state) + return getEntriesPage(pageable, state, permitQuery) .map(entry -> mapper.toDTO(entry, validThreshold)); } @@ -141,20 +186,38 @@ public Optional getEntryDetailDTO(String uuid) { } @RequiredEnabledIndexFeature - public IndexEntryInfoDTO getEntriesInfo() { + public IndexEntryInfoDTO getEntriesInfo(String permitQuery) { + final List permit = getPermits(permitQuery); final Instant validThreshold = getValidThreshold(); final Map entriesCount = new HashMap<>(); - entriesCount.put("ALL", repository.count()); - entriesCount.put(UNKNOWN.name(), repository.countAllByStateEquals(IndexEntryState.Unknown)); - entriesCount.put(ACTIVE.name(), - repository.countAllByStateEqualsAndLastRetrievalTimeAfter( - IndexEntryState.Valid, validThreshold)); - entriesCount.put(INACTIVE.name(), - repository.countAllByStateEqualsAndLastRetrievalTimeBefore( - IndexEntryState.Valid, validThreshold)); - entriesCount.put(UNREACHABLE.name(), repository.countAllByStateEquals( - IndexEntryState.Unreachable)); - entriesCount.put(INVALID.name(), repository.countAllByStateEquals(IndexEntryState.Invalid)); + entriesCount.put( + FILTER_ALL, + repository.countAllByPermitIn(permit) + ); + entriesCount.put( + UNKNOWN.name(), + repository.countAllByStateEqualsAndPermitIn(IndexEntryState.Unknown, permit) + ); + entriesCount.put( + ACTIVE.name(), + repository.countAllByStateEqualsAndLastRetrievalTimeAfterAndPermitIn( + IndexEntryState.Valid, validThreshold, permit + ) + ); + entriesCount.put( + INACTIVE.name(), + repository.countAllByStateEqualsAndLastRetrievalTimeBeforeAndPermitIn( + IndexEntryState.Valid, validThreshold, permit + ) + ); + entriesCount.put( + UNREACHABLE.name(), + repository.countAllByStateEqualsAndPermitIn(IndexEntryState.Unreachable, permit) + ); + entriesCount.put( + INVALID.name(), + repository.countAllByStateEqualsAndPermitIn(IndexEntryState.Invalid, permit) + ); return new IndexEntryInfoDTO(entriesCount); } @@ -163,6 +226,7 @@ public IndexEntry storeEntry(@Valid PingDTO pingDTO) { final String clientUrl = pingDTO.getClientUrl(); final Optional entity = repository.findByClientUrl(clientUrl); final Instant now = Instant.now(); + final IndexSettings settings = indexSettingsService.getOrDefaults(); final IndexEntry entry; if (entity.isPresent()) { @@ -175,6 +239,12 @@ public IndexEntry storeEntry(@Valid PingDTO pingDTO) { entry.setUuid(UUID.randomUUID().toString()); entry.setClientUrl(clientUrl); entry.setRegistrationTime(now); + if (settings.getAutoPermit()) { + entry.setPermit(IndexEntryPermit.ACCEPTED); + } + else { + entry.setPermit(IndexEntryPermit.PENDING); + } } entry.setModificationTime(now); @@ -190,6 +260,17 @@ public void deleteEntry(String uuid) throws MetadataRepositoryException { repository.delete(entry); } + @Async + public void harvest(String clientUrl) throws MetadataRepositoryException { + log.info("Checking index entry for '{}'", clientUrl); + final Optional indexEntry = getEntryByClientUrl(clientUrl); + if (indexEntry.isEmpty() || indexEntry.get().getPermit() != IndexEntryPermit.ACCEPTED) { + log.info("Skipping (not ACCEPTED entry) '{}'", clientUrl); + return; + } + harvesterService.harvest(clientUrl); + } + private Instant getValidThreshold() { return Instant.now() .minus(indexSettingsService.getOrDefaults().getPing().getValidDuration()); @@ -204,4 +285,17 @@ public Model getEntryHarvestedData(String uuid) throws MetadataRepositoryExcepti model.addAll(genericMetadataRepository.find(i(entry.getClientUrl()))); return model; } + + public Optional updateEntry(String uuid, IndexEntryUpdateDTO reqDto) { + final Optional entry = getEntry(uuid); + if (entry.isPresent() && !reqDto.getPermit().equals(entry.get().getPermit())) { + entry.get().setPermit(reqDto.getPermit()); + repository.save(entry.get()); + } + return getEntryDetailDTO(uuid); + } + + public Optional getEntryByClientUrl(String clientUrl) { + return repository.findByClientUrl(clientUrl); + } } diff --git a/src/main/java/nl/dtls/fairdatapoint/service/index/harvester/HarvesterService.java b/src/main/java/nl/dtls/fairdatapoint/service/index/harvester/HarvesterService.java index f30641b3f..a18d5138d 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/index/harvester/HarvesterService.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/index/harvester/HarvesterService.java @@ -40,10 +40,7 @@ import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import static java.util.Optional.ofNullable; import static nl.dtls.fairdatapoint.entity.metadata.MetadataGetter.getChildren; diff --git a/src/main/java/nl/dtls/fairdatapoint/service/index/settings/IndexSettingsMapper.java b/src/main/java/nl/dtls/fairdatapoint/service/index/settings/IndexSettingsMapper.java index 67f4eaf18..adb680da6 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/index/settings/IndexSettingsMapper.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/index/settings/IndexSettingsMapper.java @@ -54,18 +54,20 @@ private IndexSettingsRetrievalDTO toRetrievalDTO( ); } - public IndexSettingsDTO toDTO(IndexSettings indexSettings) { + public IndexSettingsDTO toDTO(IndexSettings indexSettings, IndexSettings defaults) { return new IndexSettingsDTO( toRetrievalDTO(indexSettings.getRetrieval()), toPingDTO(indexSettings.getPing()), - indexSettings.equals(IndexSettings.getDefault()) + indexSettings.getAutoPermit(), + indexSettings.equals(defaults) ); } public IndexSettingsUpdateDTO toUpdateDTO(IndexSettings indexSettings) { return new IndexSettingsUpdateDTO( toRetrievalDTO(indexSettings.getRetrieval()), - toPingDTO(indexSettings.getPing()) + toPingDTO(indexSettings.getPing()), + indexSettings.getAutoPermit() ); } @@ -97,6 +99,7 @@ public IndexSettings fromUpdateDTO(IndexSettingsUpdateDTO dto, IndexSettings ind .toBuilder() .ping(fromDTO(dto.getPing(), indexSettings.getPing())) .retrieval(fromDTO(dto.getRetrieval(), indexSettings.getRetrieval())) + .autoPermit(dto.getAutoPermit()) .build(); } } diff --git a/src/main/java/nl/dtls/fairdatapoint/service/index/settings/IndexSettingsService.java b/src/main/java/nl/dtls/fairdatapoint/service/index/settings/IndexSettingsService.java index 8de52471b..1cb93be00 100644 --- a/src/main/java/nl/dtls/fairdatapoint/service/index/settings/IndexSettingsService.java +++ b/src/main/java/nl/dtls/fairdatapoint/service/index/settings/IndexSettingsService.java @@ -26,8 +26,11 @@ import nl.dtls.fairdatapoint.api.dto.index.ping.PingDTO; import nl.dtls.fairdatapoint.api.dto.index.settings.IndexSettingsDTO; import nl.dtls.fairdatapoint.api.dto.index.settings.IndexSettingsUpdateDTO; +import nl.dtls.fairdatapoint.config.properties.InstanceProperties; import nl.dtls.fairdatapoint.database.mongo.repository.IndexSettingsRepository; import nl.dtls.fairdatapoint.entity.index.settings.IndexSettings; +import nl.dtls.fairdatapoint.entity.index.settings.IndexSettingsPing; +import nl.dtls.fairdatapoint.entity.index.settings.IndexSettingsRetrieval; import nl.dtls.fairdatapoint.service.index.common.RequiredEnabledIndexFeature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -44,6 +47,9 @@ public class IndexSettingsService { @Autowired private IndexSettingsMapper mapper; + @Autowired + private InstanceProperties instanceProperties; + @RequiredEnabledIndexFeature public boolean isPingDenied(PingDTO ping) { log.info("Checking if ping.clientUrl is on deny list: " + ping.getClientUrl()); @@ -56,21 +62,33 @@ public boolean isPingDenied(PingDTO ping) { @RequiredEnabledIndexFeature public IndexSettings getOrDefaults() { - return repository.findFirstBy().orElse(IndexSettings.getDefault()); + return repository.findFirstBy().orElse(getDefaults()); } @RequiredEnabledIndexFeature public IndexSettingsDTO getCurrentSettings() { - return mapper.toDTO(getOrDefaults()); + return mapper.toDTO(getOrDefaults(), getDefaults()); + } + + @RequiredEnabledIndexFeature + public IndexSettings getDefaults() { + final IndexSettings settings = new IndexSettings(); + settings.setPing(IndexSettingsPing.getDefault()); + settings.setRetrieval(IndexSettingsRetrieval.getDefault()); + settings.setAutoPermit(instanceProperties.isIndexAutoPermit()); + return settings; } @RequiredEnabledIndexFeature public IndexSettingsDTO updateSettings(IndexSettingsUpdateDTO dto) { - return mapper.toDTO(repository.save(mapper.fromUpdateDTO(dto, getOrDefaults()))); + return mapper.toDTO( + repository.save(mapper.fromUpdateDTO(dto, getOrDefaults())), + getDefaults() + ); } @RequiredEnabledIndexFeature public IndexSettingsDTO resetSettings() { - return updateSettings(mapper.toUpdateDTO(IndexSettings.getDefault())); + return updateSettings(mapper.toUpdateDTO(getDefaults())); } } diff --git a/src/main/java/nl/dtls/fairdatapoint/util/HttpUtil.java b/src/main/java/nl/dtls/fairdatapoint/util/HttpUtil.java index 3d451c8f0..0210134e1 100644 --- a/src/main/java/nl/dtls/fairdatapoint/util/HttpUtil.java +++ b/src/main/java/nl/dtls/fairdatapoint/util/HttpUtil.java @@ -72,7 +72,7 @@ public static String getClientIpAddress(HttpServletRequest request, Boolean behi if (behindProxy) { for (String header : IP_HEADER_CANDIDATES) { final String ipList = request.getHeader(header); - if (ipList != null && ipList.length() != 0 && !"unknown".equalsIgnoreCase(ipList)) { + if (ipList != null && !ipList.isEmpty() && !"unknown".equalsIgnoreCase(ipList)) { return ipList.split(",")[0]; } } diff --git a/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 160232d47..0bd593633 100644 --- a/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -15,6 +15,11 @@ "type": "java.lang.Boolean", "description": "Turn on if you want to run FAIR Data Point as FAIR Data Point Index" }, + { + "name": "instance.indexAutoPermit", + "type": "java.lang.Boolean", + "description": "Turn on if you want automatically permit new entries that ping the Index" + }, { "name": "security.jwt.token.secret-key", "type": "java.lang.String", diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index f791ac405..f09eaeec7 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,5 +1,6 @@ instance: index: ${FDP_INDEX:false} + indexAutoPermit: ${FDP_INDEX_AUTOPERMIT:true} clientUrl: ${FDP_CLIENT_URL:http://localhost:8080} persistentUrl: ${FDP_PERSISTENT_URL:http://localhost:8080} behindProxy: ${FDP_BEHIND_PROXY:true} diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/admin/List_Trigger_POST.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/admin/List_Trigger_POST.java index 9c81a0262..297d8fb46 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/admin/List_Trigger_POST.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/admin/List_Trigger_POST.java @@ -26,6 +26,7 @@ import nl.dtls.fairdatapoint.api.dto.index.ping.PingDTO; import nl.dtls.fairdatapoint.database.mongo.repository.EventRepository; import nl.dtls.fairdatapoint.database.mongo.repository.IndexEntryRepository; +import nl.dtls.fairdatapoint.database.mongo.repository.IndexSettingsRepository; import nl.dtls.fairdatapoint.entity.index.entry.IndexEntry; import nl.dtls.fairdatapoint.entity.index.event.Event; import nl.dtls.fairdatapoint.entity.index.event.EventType; @@ -33,7 +34,6 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -56,6 +56,9 @@ public class List_Trigger_POST extends WebIntegrationTest { @Autowired private IndexEntryRepository indexEntryRepository; + @Autowired + private IndexSettingsRepository indexSettingsRepository; + private final ParameterizedTypeReference responseType = new ParameterizedTypeReference<>() { }; @@ -153,6 +156,8 @@ public void res400_malformedUrl() { @DisplayName("HTTP 204: trigger one") public void res204_triggerOne() { // GIVEN: prepare data + indexEntryRepository.deleteAll(); + indexSettingsRepository.deleteAll(); IndexEntry entry = TestIndexEntryFixtures.entryExample(); indexEntryRepository.save(entry); PingDTO reqDTO = reqDTO(entry.getClientUrl()); @@ -177,6 +182,8 @@ public void res204_triggerOne() { @DisplayName("HTTP 404: trigger non-existing") public void res404_triggerOne() { // GIVEN: prepare data + indexEntryRepository.deleteAll(); + indexSettingsRepository.deleteAll(); IndexEntry entry = TestIndexEntryFixtures.entryExample(); PingDTO reqDTO = reqDTO(entry.getClientUrl()); diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/entry/List_All_GET.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/entry/List_All_GET.java index 06821ff6c..33f9b3ac6 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/entry/List_All_GET.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/entry/List_All_GET.java @@ -26,15 +26,14 @@ import nl.dtls.fairdatapoint.api.dto.index.entry.IndexEntryDTO; import nl.dtls.fairdatapoint.database.mongo.repository.IndexEntryRepository; import nl.dtls.fairdatapoint.entity.index.entry.IndexEntry; +import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryPermit; import nl.dtls.fairdatapoint.utils.TestIndexEntryFixtures; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.RequestEntity; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; +import org.springframework.web.util.UriComponentsBuilder; import java.net.URI; import java.util.List; @@ -57,6 +56,12 @@ private URI url() { return URI.create("/index/entries/all"); } + private URI urlWithPermit(String permitQuery) { + return UriComponentsBuilder.fromUri(url()) + .queryParam("permit", permitQuery) + .build().toUri(); + } + @Test @DisplayName("HTTP 200: list empty") public void res200_listEmpty() { @@ -134,4 +139,180 @@ public void res200_listMany() { is(equalTo(entries.get(i).getClientUrl()))); } } + + @Test + @DisplayName("HTTP 200: list accepted") + public void res200_listAccepted() { + // GIVEN: prepare data + indexEntryRepository.deleteAll(); + List entries = TestIndexEntryFixtures.entriesPermits(); + indexEntryRepository.saveAll(entries); + + // AND: prepare request + RequestEntity request = RequestEntity + .get(urlWithPermit("accepted")) + .accept(MediaType.APPLICATION_JSON) + .build(); + + // WHEN + ResponseEntity> result = client.exchange(request, responseType); + + // THEN + assertThat("Correct response code is received", result.getStatusCode(), + is(equalTo(HttpStatus.OK))); + assertThat("Response body is not null", result.getBody(), + is(notNullValue())); + assertThat("Correct number of entries is in the response", result.getBody().size(), + is(equalTo(1))); + assertThat("Response body is not null", result.getBody().get(0).getPermit(), + is(notNullValue())); + assertThat("Response body is not null", result.getBody().get(0).getPermit(), + is(equalTo(IndexEntryPermit.ACCEPTED))); + } + + @Test + @DisplayName("HTTP 200: list rejected (non-admin)") + public void res200_listRejected_nonAdmin() { + // GIVEN: prepare data + indexEntryRepository.deleteAll(); + List entries = TestIndexEntryFixtures.entriesPermits(); + indexEntryRepository.saveAll(entries); + + // AND: prepare request + RequestEntity request = RequestEntity + .get(urlWithPermit("rejected")) + .accept(MediaType.APPLICATION_JSON) + .build(); + + // WHEN + ResponseEntity> result = client.exchange(request, responseType); + + // THEN + assertThat("Correct response code is received", result.getStatusCode(), + is(equalTo(HttpStatus.OK))); + assertThat("Response body is not null", result.getBody(), + is(notNullValue())); + assertThat("Correct number of entries is in the response", result.getBody().size(), + is(equalTo(1))); + assertThat("Response body is not null", result.getBody().get(0).getPermit(), + is(notNullValue())); + assertThat("Response body is not null", result.getBody().get(0).getPermit(), + is(equalTo(IndexEntryPermit.ACCEPTED))); + } + + @Test + @DisplayName("HTTP 200: list rejected (admin)") + public void res200_listRejected_admin() { + // GIVEN: prepare data + indexEntryRepository.deleteAll(); + List entries = TestIndexEntryFixtures.entriesPermits(); + indexEntryRepository.saveAll(entries); + + // AND: prepare request + RequestEntity request = RequestEntity + .get(urlWithPermit("rejected")) + .header(HttpHeaders.AUTHORIZATION, ADMIN_TOKEN) + .accept(MediaType.APPLICATION_JSON) + .build(); + + // WHEN + ResponseEntity> result = client.exchange(request, responseType); + + // THEN + assertThat("Correct response code is received", result.getStatusCode(), + is(equalTo(HttpStatus.OK))); + assertThat("Response body is not null", result.getBody(), + is(notNullValue())); + assertThat("Correct number of entries is in the response", result.getBody().size(), + is(equalTo(1))); + assertThat("Response body is not null", result.getBody().get(0).getPermit(), + is(notNullValue())); + assertThat("Response body is not null", result.getBody().get(0).getPermit(), + is(equalTo(IndexEntryPermit.REJECTED))); + } + + @Test + @DisplayName("HTTP 200: list pending (admin)") + public void res200_listPending_admin() { + // GIVEN: prepare data + indexEntryRepository.deleteAll(); + List entries = TestIndexEntryFixtures.entriesPermits(); + indexEntryRepository.saveAll(entries); + + // AND: prepare request + RequestEntity request = RequestEntity + .get(urlWithPermit("pending")) + .header(HttpHeaders.AUTHORIZATION, ADMIN_TOKEN) + .accept(MediaType.APPLICATION_JSON) + .build(); + + // WHEN + ResponseEntity> result = client.exchange(request, responseType); + + // THEN + assertThat("Correct response code is received", result.getStatusCode(), + is(equalTo(HttpStatus.OK))); + assertThat("Response body is not null", result.getBody(), + is(notNullValue())); + assertThat("Correct number of entries is in the response", result.getBody().size(), + is(equalTo(1))); + assertThat("Response body is not null", result.getBody().get(0).getPermit(), + is(notNullValue())); + assertThat("Response body is not null", result.getBody().get(0).getPermit(), + is(equalTo(IndexEntryPermit.PENDING))); + } + + @Test + @DisplayName("HTTP 200: list combined (admin)") + public void res200_listCombined_admin() { + // GIVEN: prepare data + indexEntryRepository.deleteAll(); + List entries = TestIndexEntryFixtures.entriesPermits(); + indexEntryRepository.saveAll(entries); + + // AND: prepare request + RequestEntity request = RequestEntity + .get(urlWithPermit("rejected,pending")) + .header(HttpHeaders.AUTHORIZATION, ADMIN_TOKEN) + .accept(MediaType.APPLICATION_JSON) + .build(); + + // WHEN + ResponseEntity> result = client.exchange(request, responseType); + + // THEN + assertThat("Correct response code is received", result.getStatusCode(), + is(equalTo(HttpStatus.OK))); + assertThat("Response body is not null", result.getBody(), + is(notNullValue())); + assertThat("Correct number of entries is in the response", result.getBody().size(), + is(equalTo(2))); + } + + @Test + @DisplayName("HTTP 200: list all (admin)") + public void res200_listAll_admin() { + // GIVEN: prepare data + indexEntryRepository.deleteAll(); + List entries = TestIndexEntryFixtures.entriesPermits(); + indexEntryRepository.saveAll(entries); + + // AND: prepare request + RequestEntity request = RequestEntity + .get(urlWithPermit("all")) + .header(HttpHeaders.AUTHORIZATION, ADMIN_TOKEN) + .accept(MediaType.APPLICATION_JSON) + .build(); + + // WHEN + ResponseEntity> result = client.exchange(request, responseType); + + // THEN + assertThat("Correct response code is received", result.getStatusCode(), + is(equalTo(HttpStatus.OK))); + assertThat("Response body is not null", result.getBody(), + is(notNullValue())); + assertThat("Correct number of entries is in the response", result.getBody().size(), + is(equalTo(3))); + } } diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/entry/List_GET.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/entry/List_GET.java index 40e834e7d..530e8b558 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/entry/List_GET.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/entry/List_GET.java @@ -26,16 +26,14 @@ import nl.dtls.fairdatapoint.api.dto.index.entry.IndexEntryDTO; import nl.dtls.fairdatapoint.database.mongo.repository.IndexEntryRepository; import nl.dtls.fairdatapoint.entity.index.entry.IndexEntry; +import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryPermit; import nl.dtls.fairdatapoint.utils.CustomPageImpl; import nl.dtls.fairdatapoint.utils.TestIndexEntryFixtures; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.RequestEntity; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; import org.springframework.web.util.UriComponentsBuilder; import java.net.URI; @@ -73,6 +71,12 @@ private URI urlWithPageSize(int page, int size) { .build().toUri(); } + private URI urlWithPermit(String permitQuery) { + return UriComponentsBuilder.fromUri(url()) + .queryParam("permit", permitQuery) + .build().toUri(); + } + @Test @DisplayName("HTTP 200: page empty") public void res200_pageEmpty() { @@ -223,4 +227,65 @@ public void res200_pageManyLast() { assertThat("There is correct number of entries in the response", result.getBody().getContent().size(), is(equalTo(lastSize))); } + + @Test + @DisplayName("HTTP 200: page accepted (default)") + public void res200_pageAcceptedDefault() { + // GIVEN: prepare data + indexEntryRepository.deleteAll(); + List entries = TestIndexEntryFixtures.entriesPermits(); + indexEntryRepository.saveAll(entries); + + // AND: prepare request + RequestEntity request = RequestEntity + .get(url()) + .accept(MediaType.APPLICATION_JSON) + .build(); + + // WHEN + ResponseEntity> result = client.exchange(request, responseType); + + // THEN + assertThat("Correct response code is received", result.getStatusCode(), is(equalTo(HttpStatus.OK))); + assertThat("Response body is not null", result.getBody(), is(notNullValue())); + assertThat("Current page is the first page", result.getBody().isFirst(), is(Boolean.TRUE)); + assertThat("Current page is the last page", result.getBody().isLast(), is(Boolean.TRUE)); + assertThat("Current page is not empty", result.getBody().isEmpty(), is(Boolean.FALSE)); + assertThat("Number of pages is 1", result.getBody().getTotalPages(), is(equalTo(1))); + assertThat("Number of elements is correct", result.getBody().getTotalElements(), + is(equalTo(Integer.toUnsignedLong(1)))); + assertThat("There is correct number of entries in the response", result.getBody().getContent().get(0).getPermit(), + is(equalTo(IndexEntryPermit.ACCEPTED))); + } + + @Test + @DisplayName("HTTP 200: page rejected (admin)") + public void res200_pageRejected() { + // GIVEN: prepare data + indexEntryRepository.deleteAll(); + List entries = TestIndexEntryFixtures.entriesPermits(); + indexEntryRepository.saveAll(entries); + + // AND: prepare request + RequestEntity request = RequestEntity + .get(urlWithPermit("rejected")) + .header(HttpHeaders.AUTHORIZATION, ADMIN_TOKEN) + .accept(MediaType.APPLICATION_JSON) + .build(); + + // WHEN + ResponseEntity> result = client.exchange(request, responseType); + + // THEN + assertThat("Correct response code is received", result.getStatusCode(), is(equalTo(HttpStatus.OK))); + assertThat("Response body is not null", result.getBody(), is(notNullValue())); + assertThat("Current page is the first page", result.getBody().isFirst(), is(Boolean.TRUE)); + assertThat("Current page is the last page", result.getBody().isLast(), is(Boolean.TRUE)); + assertThat("Current page is not empty", result.getBody().isEmpty(), is(Boolean.FALSE)); + assertThat("Number of pages is 1", result.getBody().getTotalPages(), is(equalTo(1))); + assertThat("Number of elements is correct", result.getBody().getTotalElements(), + is(equalTo(Integer.toUnsignedLong(1)))); + assertThat("There is correct number of entries in the response", result.getBody().getContent().get(0).getPermit(), + is(equalTo(IndexEntryPermit.REJECTED))); + } } diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/entry/List_Info_GET.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/entry/List_Info_GET.java index 29c2ce0c7..811716979 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/entry/List_Info_GET.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/entry/List_Info_GET.java @@ -24,16 +24,19 @@ import nl.dtls.fairdatapoint.WebIntegrationTest; import nl.dtls.fairdatapoint.api.dto.index.entry.IndexEntryInfoDTO; +import nl.dtls.fairdatapoint.database.mongo.repository.IndexEntryRepository; +import nl.dtls.fairdatapoint.entity.index.entry.IndexEntry; +import nl.dtls.fairdatapoint.utils.TestIndexEntryFixtures; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.RequestEntity; -import org.springframework.http.ResponseEntity; +import org.springframework.http.*; +import org.springframework.web.util.UriComponentsBuilder; import java.net.URI; import java.util.HashMap; +import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; @@ -43,6 +46,9 @@ @DisplayName("GET /index/entries/info") public class List_Info_GET extends WebIntegrationTest { + @Autowired + private IndexEntryRepository indexEntryRepository; + private final ParameterizedTypeReference responseType = new ParameterizedTypeReference<>() { }; @@ -50,8 +56,14 @@ private URI url() { return URI.create("/index/entries/info"); } + private URI urlWithPermit(String permitQuery) { + return UriComponentsBuilder.fromUri(url()) + .queryParam("permit", permitQuery) + .build().toUri(); + } + @Test - @DisplayName("HTTP 200") + @DisplayName("HTTP 200: list default") public void res200_listMany() { // GIVEN: Prepare request RequestEntity request = RequestEntity @@ -75,7 +87,77 @@ public void res200_listMany() { // THEN: assertThat("Correct response code is received", result.getStatusCode(), is(equalTo(HttpStatus.OK))); assertThat("Response body is not null", result.getBody(), is(notNullValue())); - assertThat("Correct number of entries is in the response", result.getBody(), - is(equalTo(expDto))); + assertThat("Correct number of entries is in the response", result.getBody().getEntriesCount(), + is(equalTo(expDto.getEntriesCount()))); + } + + @Test + @DisplayName("HTTP 200: list rejected (admin)") + public void res200_listRejected() { + // GIVEN: prepare data + indexEntryRepository.deleteAll(); + List entries = TestIndexEntryFixtures.entriesPermits(); + indexEntryRepository.saveAll(entries); + + // GIVEN: Prepare request + RequestEntity request = RequestEntity + .get(urlWithPermit("rejected")) + .header(HttpHeaders.AUTHORIZATION, ADMIN_TOKEN) + .accept(MediaType.APPLICATION_JSON) + .build(); + + // AND: Prepare expectation + IndexEntryInfoDTO expDto = new IndexEntryInfoDTO(new HashMap<>() {{ + put("ALL", 1L); + put("ACTIVE", 0L); + put("INACTIVE", 0L); + put("UNKNOWN", 0L); + put("INVALID", 1L); + put("UNREACHABLE", 0L); + }}); + + // WHEN: + ResponseEntity result = client.exchange(request, responseType); + + // THEN: + assertThat("Correct response code is received", result.getStatusCode(), is(equalTo(HttpStatus.OK))); + assertThat("Response body is not null", result.getBody(), is(notNullValue())); + assertThat("Correct number of entries is in the response", result.getBody().getEntriesCount(), + is(equalTo(expDto.getEntriesCount()))); + } + + @Test + @DisplayName("HTTP 200: list combined (admin)") + public void res200_listCombined() { + // GIVEN: prepare data + indexEntryRepository.deleteAll(); + List entries = TestIndexEntryFixtures.entriesPermits(); + indexEntryRepository.saveAll(entries); + + // GIVEN: Prepare request + RequestEntity request = RequestEntity + .get(urlWithPermit("rejected,pending,accepted")) + .header(HttpHeaders.AUTHORIZATION, ADMIN_TOKEN) + .accept(MediaType.APPLICATION_JSON) + .build(); + + // AND: Prepare expectation + IndexEntryInfoDTO expDto = new IndexEntryInfoDTO(new HashMap<>() {{ + put("ALL", 3L); + put("ACTIVE", 0L); + put("INACTIVE", 0L); + put("UNKNOWN", 0L); + put("INVALID", 3L); + put("UNREACHABLE", 0L); + }}); + + // WHEN: + ResponseEntity result = client.exchange(request, responseType); + + // THEN: + assertThat("Correct response code is received", result.getStatusCode(), is(equalTo(HttpStatus.OK))); + assertThat("Response body is not null", result.getBody(), is(notNullValue())); + assertThat("Correct number of entries is in the response", result.getBody().getEntriesCount(), + is(equalTo(expDto.getEntriesCount()))); } } diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/settings/List_DELETE.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/settings/List_DELETE.java index 7fd318fa5..bb1a0b9d5 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/settings/List_DELETE.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/settings/List_DELETE.java @@ -84,7 +84,12 @@ private IndexSettings customSettings() { @DisplayName("HTTP 200: default settings") public void res200_defaultSettings() { // GIVEN: prepare data - IndexSettings settings = IndexSettings.getDefault(); + IndexSettings settings = IndexSettings + .builder() + .ping(IndexSettingsPing.getDefault()) + .retrieval(IndexSettingsRetrieval.getDefault()) + .autoPermit(true) + .build(); indexSettingsRepository.deleteAll(); // AND: prepare request @@ -113,7 +118,12 @@ public void res200_defaultSettings() { @DisplayName("HTTP 200: custom settings") public void res200_customSettings() { // GIVEN: prepare data - IndexSettings settings = IndexSettings.getDefault(); + IndexSettings settings = IndexSettings + .builder() + .ping(IndexSettingsPing.getDefault()) + .retrieval(IndexSettingsRetrieval.getDefault()) + .autoPermit(true) + .build(); IndexSettings customSettings = customSettings(); indexSettingsRepository.deleteAll(); indexSettingsRepository.insert(customSettings); diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/settings/List_GET.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/settings/List_GET.java index 574830827..ec3832b29 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/settings/List_GET.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/settings/List_GET.java @@ -84,7 +84,12 @@ private IndexSettings customSettings() { @DisplayName("HTTP 200: default settings") public void res200_defaultSettings() { // GIVEN: prepare data - IndexSettings settings = IndexSettings.getDefault(); + IndexSettings settings = IndexSettings + .builder() + .ping(IndexSettingsPing.getDefault()) + .retrieval(IndexSettingsRetrieval.getDefault()) + .autoPermit(true) + .build(); indexSettingsRepository.deleteAll(); // AND: prepare request diff --git a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/settings/List_PUT.java b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/settings/List_PUT.java index b00ce2255..41b7b74fc 100644 --- a/src/test/java/nl/dtls/fairdatapoint/acceptance/index/settings/List_PUT.java +++ b/src/test/java/nl/dtls/fairdatapoint/acceptance/index/settings/List_PUT.java @@ -80,6 +80,7 @@ private IndexSettings customSettings1() { .timeout(Duration.ofSeconds(55)) .build() ) + .autoPermit(true) .build(); } @@ -103,6 +104,7 @@ private IndexSettingsUpdateDTO customSettingsUpdateDTO() { retrievalDTO.setRateLimitWait(customSettings.getRetrieval().getRateLimitWait().toString()); retrievalDTO.setTimeout(customSettings.getRetrieval().getTimeout().toString()); dto.setRetrieval(retrievalDTO); + dto.setAutoPermit(true); return dto; } diff --git a/src/test/java/nl/dtls/fairdatapoint/utils/TestIndexEntryFixtures.java b/src/test/java/nl/dtls/fairdatapoint/utils/TestIndexEntryFixtures.java index 3216d75a0..1a69b3a04 100644 --- a/src/test/java/nl/dtls/fairdatapoint/utils/TestIndexEntryFixtures.java +++ b/src/test/java/nl/dtls/fairdatapoint/utils/TestIndexEntryFixtures.java @@ -23,6 +23,7 @@ package nl.dtls.fairdatapoint.utils; import nl.dtls.fairdatapoint.entity.index.entry.IndexEntry; +import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryPermit; import nl.dtls.fairdatapoint.entity.index.entry.IndexEntryState; import java.time.Instant; @@ -40,6 +41,14 @@ private static IndexEntry newIndexEntry(String uuid, String clientUrl, Instant t indexEntry.setModificationTime(timestamp); indexEntry.setRegistrationTime(timestamp); indexEntry.setState(IndexEntryState.Invalid); + indexEntry.setPermit(IndexEntryPermit.ACCEPTED); + return indexEntry; + } + + private static IndexEntry newIndexEntry(String uuid, String clientUrl, Instant timestamp, + IndexEntryPermit permit) { + IndexEntry indexEntry = newIndexEntry(uuid, clientUrl, timestamp); + indexEntry.setPermit(permit); return indexEntry; } @@ -56,6 +65,15 @@ public static List entriesFew() { ); } + public static List entriesPermits() { + Instant ref = Instant.now(); + return Arrays.asList( + newIndexEntry("09200532-18b4-4721-86dd-fbfa13ec78c3", "http://example.com/accepted", ref, IndexEntryPermit.ACCEPTED), + newIndexEntry("b6cfa934-dc67-4b88-b8f9-c63448c8272c", "http://example.com/rejected", ref, IndexEntryPermit.REJECTED), + newIndexEntry("da9ddfb8-6fdb-41b1-889e-387c8cbafc39", "http://example.com/pending", ref, IndexEntryPermit.PENDING) + ); + } + public static List entriesN(long n) { ArrayList entries = new ArrayList<>(); Instant ref = Instant.now();