diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/README.MD b/ldes-fragmentisers/ldes-fragmentisers-timebased/README.MD deleted file mode 100644 index 1a3cfe29bc..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/README.MD +++ /dev/null @@ -1,14 +0,0 @@ -# Timebased fragmentation [DEPRECATED] -This fragmentation is currently no longer supported as it is a predecessor of [the pagination fragmentiser](../ldes-fragmentisers-pagination). -Please use pagination instead. - -### Algorithm -This fragmentiser will create an initial fragment with the current timestamp when processing a member. -Members are added to the fragment until the member limit is reached. When the fragment member limit is reached, a -next fragment is created with a new current timestamp. - - -### Reasons for deprecating this fragmentiser: -1. This fragmentiser follows the algorithm of pagination but without the semantics. -2. For a correct timebased fragmentation, members of the fragment should be checked and their value -for a given property should be used to create the correct relations. This is not the case, and there is currently no demand to have this implemented. diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/pom.xml b/ldes-fragmentisers/ldes-fragmentisers-timebased/pom.xml deleted file mode 100644 index 2591032fad..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/pom.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - ldes-fragmentisers - be.vlaanderen.informatievlaanderen.vsds - 2.1.0-SNAPSHOT - - 4.0.0 - - ldes-fragmentisers-timebased - - - ../.. - - - - - - org.springframework.boot - spring-boot-starter - - - org.springframework.boot - spring-boot-autoconfigure - - - org.springframework.boot - spring-boot-configuration-processor - - - - be.vlaanderen.informatievlaanderen.vsds - ldes-fragmentisers-common - ${project.version} - - - - - ${project.artifactId} - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - \ No newline at end of file diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimeBasedFragmentationStrategyAutoConfiguration.java b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimeBasedFragmentationStrategyAutoConfiguration.java deleted file mode 100644 index 45846ca350..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimeBasedFragmentationStrategyAutoConfiguration.java +++ /dev/null @@ -1,25 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -import static be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.TimebasedFragmentationStrategy.TIMEBASED_FRAGMENTATION; - -@Configuration -@EnableConfigurationProperties() -@ComponentScan("be.vlaanderen.informatievlaanderen.ldes.server") -public class TimeBasedFragmentationStrategyAutoConfiguration { - - private static final Logger LOGGER = LoggerFactory.getLogger(TimeBasedFragmentationStrategyAutoConfiguration.class); - - @Bean(TIMEBASED_FRAGMENTATION) - public TimebasedFragmentationStrategyWrapper timebasedFragmentationStrategyWrapper() { - LOGGER.warn("Using deprecated timebased fragmentation. For more information, refer to " + - "https://github.com/Informatievlaanderen/VSDS-LDESServer4J/blob/main/ldes-fragmentisers/ldes-fragmentisers-timebased/README.MD"); - return new TimebasedFragmentationStrategyWrapper(); - } -} diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimebasedFragmentationStrategy.java b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimebasedFragmentationStrategy.java deleted file mode 100644 index ca4e2819a1..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimebasedFragmentationStrategy.java +++ /dev/null @@ -1,42 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased; - -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.FragmentationStrategy; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.FragmentationStrategyDecorator; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.entities.Fragment; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.repository.FragmentRepository; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.services.OpenFragmentProvider; -import io.micrometer.observation.Observation; -import io.micrometer.observation.ObservationRegistry; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.jena.rdf.model.Model; - -public class TimebasedFragmentationStrategy extends FragmentationStrategyDecorator { - public static final String TIMEBASED_FRAGMENTATION = "TimebasedFragmentation"; - private final OpenFragmentProvider openFragmentProvider; - - private final ObservationRegistry observationRegistry; - - public TimebasedFragmentationStrategy(FragmentationStrategy fragmentationStrategy, - OpenFragmentProvider openFragmentProvider, ObservationRegistry observationRegistry, - FragmentRepository fragmentRepository) { - super(fragmentationStrategy, fragmentRepository); - this.openFragmentProvider = openFragmentProvider; - this.observationRegistry = observationRegistry; - } - - @Override - public void addMemberToFragment(Fragment parentFragment, String memberId, Model memberModel, - Observation parentObservation) { - Observation timebasedFragmentationObservation = Observation.createNotStarted("timebased fragmentation", - observationRegistry) - .parentObservation(parentObservation) - .start(); - Pair ldesFragment = openFragmentProvider - .retrieveOpenFragmentOrCreateNewFragment(parentFragment); - if (Boolean.TRUE.equals(ldesFragment.getRight())) { - super.addRelationFromParentToChild(parentFragment, ldesFragment.getLeft()); - } - super.addMemberToFragment(ldesFragment.getLeft(), memberId, memberModel, timebasedFragmentationObservation); - timebasedFragmentationObservation.stop(); - } -} diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimebasedFragmentationStrategyWrapper.java b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimebasedFragmentationStrategyWrapper.java deleted file mode 100644 index a605417ddf..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimebasedFragmentationStrategyWrapper.java +++ /dev/null @@ -1,54 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased; - -import be.vlaanderen.informatievlaanderen.ldes.server.domain.model.ConfigProperties; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.FragmentationStrategy; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.FragmentationStrategyWrapper; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.repository.FragmentRepository; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.config.TimebasedFragmentationConfig; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.services.OpenFragmentProvider; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.services.TimeBasedFragmentCreator; -import io.micrometer.observation.ObservationRegistry; -import org.apache.jena.rdf.model.Property; -import org.springframework.context.ApplicationContext; - -import static be.vlaanderen.informatievlaanderen.ldes.server.domain.constants.RdfConstants.PROV_GENERATED_AT_TIME; -import static be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.config.TimebasedProperties.FRAGMENTATION_PATH; -import static be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.config.TimebasedProperties.MEMBER_LIMIT; -import static org.apache.jena.rdf.model.ResourceFactory.createProperty; - -public class TimebasedFragmentationStrategyWrapper implements FragmentationStrategyWrapper { - - public FragmentationStrategy wrapFragmentationStrategy(ApplicationContext applicationContext, - FragmentationStrategy fragmentationStrategy, ConfigProperties fragmentationProperties) { - FragmentRepository fragmentRepository = applicationContext.getBean(FragmentRepository.class); - ObservationRegistry observationRegistry = applicationContext.getBean(ObservationRegistry.class); - - OpenFragmentProvider openFragmentProvider = getOpenFragmentProvider(fragmentationProperties, - fragmentRepository); - return new TimebasedFragmentationStrategy(fragmentationStrategy, - openFragmentProvider, observationRegistry, fragmentRepository); - - } - - private OpenFragmentProvider getOpenFragmentProvider(ConfigProperties properties, - FragmentRepository fragmentRepository) { - TimebasedFragmentationConfig timebasedFragmentationConfig = createTimebasedFragmentationConfig(properties); - TimeBasedFragmentCreator timeBasedFragmentCreator = getTimeBasedFragmentCreator( - fragmentRepository, - timebasedFragmentationConfig.fragmentationPath()); - return new OpenFragmentProvider(timeBasedFragmentCreator, fragmentRepository, - timebasedFragmentationConfig.memberLimit()); - } - - private TimeBasedFragmentCreator getTimeBasedFragmentCreator(FragmentRepository fragmentRepository, - Property timebasedFragmentationConfig) { - return new TimeBasedFragmentCreator( - fragmentRepository, - timebasedFragmentationConfig); - } - - private TimebasedFragmentationConfig createTimebasedFragmentationConfig(ConfigProperties properties) { - return new TimebasedFragmentationConfig(Long.valueOf(properties.get(MEMBER_LIMIT)), - createProperty(properties.getOrDefault(FRAGMENTATION_PATH, PROV_GENERATED_AT_TIME))); - } -} diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/config/TimebasedFragmentationConfig.java b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/config/TimebasedFragmentationConfig.java deleted file mode 100644 index 6fb8d4f5cc..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/config/TimebasedFragmentationConfig.java +++ /dev/null @@ -1,6 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.config; - -import org.apache.jena.rdf.model.Property; - -public record TimebasedFragmentationConfig(Long memberLimit, Property fragmentationPath ) { -} diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/config/TimebasedProperties.java b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/config/TimebasedProperties.java deleted file mode 100644 index ad4e9dbfc2..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/config/TimebasedProperties.java +++ /dev/null @@ -1,10 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.config; - -public class TimebasedProperties { - private TimebasedProperties() { - } - - public static final String MEMBER_LIMIT = "memberLimit"; - public static final String FRAGMENTATION_PATH = "fragmentationPath"; - -} diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/services/OpenFragmentProvider.java b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/services/OpenFragmentProvider.java deleted file mode 100644 index fb006c2d16..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/services/OpenFragmentProvider.java +++ /dev/null @@ -1,43 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.services; - -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.entities.Fragment; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.repository.FragmentRepository; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; - -public class OpenFragmentProvider { - - private final TimeBasedFragmentCreator fragmentCreator; - private final FragmentRepository fragmentRepository; - private final Long memberLimit; - - public OpenFragmentProvider(TimeBasedFragmentCreator fragmentCreator, - FragmentRepository fragmentRepository, Long memberLimit) { - this.fragmentCreator = fragmentCreator; - this.fragmentRepository = fragmentRepository; - this.memberLimit = memberLimit; - } - - public Pair retrieveOpenFragmentOrCreateNewFragment(Fragment parentFragment) { - return fragmentRepository - .retrieveOpenChildFragment(parentFragment.getFragmentId()) - .map(fragment -> { - if (needsToCreateNewFragment(fragment)) { - Fragment newFragment = fragmentCreator.createNewFragment(fragment, parentFragment); - fragmentRepository.saveFragment(newFragment); - return new ImmutablePair<>(newFragment, false); - } else { - return new ImmutablePair<>(fragment, false); - } - }) - .orElseGet(() -> { - Fragment newFragment = fragmentCreator.createNewFragment(parentFragment); - fragmentRepository.saveFragment(newFragment); - return new ImmutablePair<>(newFragment, true); - }); - } - - public boolean needsToCreateNewFragment(Fragment fragment) { - return fragment.getNrOfMembersAdded() >= memberLimit; - } -} diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/services/TimeBasedFragmentCreator.java b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/services/TimeBasedFragmentCreator.java deleted file mode 100644 index 88a8d9bfd1..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/services/TimeBasedFragmentCreator.java +++ /dev/null @@ -1,74 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.services; - -import be.vlaanderen.informatievlaanderen.ldes.server.domain.model.FragmentPair; -import be.vlaanderen.informatievlaanderen.ldes.server.domain.model.TreeRelation; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.entities.Fragment; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.exceptions.MissingFragmentValueException; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.repository.FragmentRepository; -import org.apache.jena.rdf.model.Property; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - -import static be.vlaanderen.informatievlaanderen.ldes.server.domain.constants.RdfConstants.TREE_GREATER_THAN_OR_EQUAL_TO_RELATION; -import static be.vlaanderen.informatievlaanderen.ldes.server.domain.constants.RdfConstants.TREE_LESSER_THAN_OR_EQUAL_TO_RELATION; - -public class TimeBasedFragmentCreator { - - public static final String DATE_TIME_TYPE = "http://www.w3.org/2001/XMLSchema#dateTime"; - private final FragmentRepository fragmentRepository; - private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); - - private final Property fragmentationPath; - private static final Logger LOGGER = LoggerFactory.getLogger(TimeBasedFragmentCreator.class); - - public TimeBasedFragmentCreator(FragmentRepository fragmentRepository, - Property fragmentationPath) { - - this.fragmentRepository = fragmentRepository; - this.fragmentationPath = fragmentationPath; - } - - public Fragment createNewFragment(Fragment parentFragment) { - return createNewFragment(null, parentFragment); - } - - public Fragment createNewFragment(Fragment fragment, - Fragment parentFragment) { - String fragmentKey = fragmentationPath.getLocalName(); - String fragmentValue = LocalDateTime.now().format(formatter); - Fragment newFragment = parentFragment.createChild(new FragmentPair(fragmentKey, fragmentValue)); - LOGGER.debug("Time based fragment created with id: {}", newFragment.getFragmentId()); - if (fragment != null) { - makeFragmentImmutableAndUpdateRelations(fragment, newFragment); - } - return newFragment; - } - - private void makeFragmentImmutableAndUpdateRelations(Fragment completeFragment, - Fragment newFragment) { - completeFragment.makeImmutable(); - String treePath = fragmentationPath.toString(); - String fragmentKey = fragmentationPath.getLocalName(); - completeFragment - .addRelation(new TreeRelation(treePath, - newFragment.getFragmentId(), - newFragment.getValueOfKey(fragmentKey).orElseThrow( - () -> new MissingFragmentValueException(newFragment.getFragmentIdString(), - fragmentKey)), - DATE_TIME_TYPE, - TREE_GREATER_THAN_OR_EQUAL_TO_RELATION)); - newFragment - .addRelation(new TreeRelation(treePath, completeFragment.getFragmentId(), - completeFragment.getValueOfKey(fragmentKey).orElseThrow( - () -> new MissingFragmentValueException(completeFragment.getFragmentIdString(), - fragmentKey)), - DATE_TIME_TYPE, - TREE_LESSER_THAN_OR_EQUAL_TO_RELATION)); - fragmentRepository.saveFragment(completeFragment); - fragmentRepository.saveFragment(newFragment); - } - -} diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/resources/META-INF/spring.factories b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 0c6d10844e..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,2 +0,0 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.TimebasedFragmentationStrategyAutoConfiguration \ No newline at end of file diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimebasedFragmentationStrategyTest.java b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimebasedFragmentationStrategyTest.java deleted file mode 100644 index ac021bf93f..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimebasedFragmentationStrategyTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased; - -import be.vlaanderen.informatievlaanderen.ldes.server.domain.model.FragmentPair; -import be.vlaanderen.informatievlaanderen.ldes.server.domain.model.LdesFragmentIdentifier; -import be.vlaanderen.informatievlaanderen.ldes.server.domain.model.ViewName; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.FragmentationStrategy; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.entities.Fragment; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.entities.Member; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.repository.FragmentRepository; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.services.OpenFragmentProvider; -import io.micrometer.observation.Observation; -import io.micrometer.observation.ObservationRegistry; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.InOrder; - -import java.util.List; - -import static org.mockito.Mockito.*; - -class TimebasedFragmentationStrategyTest { - - private static final ViewName VIEW_NAME = new ViewName("collectionName", "view"); - private final OpenFragmentProvider openFragmentProvider = mock(OpenFragmentProvider.class); - private final FragmentationStrategy decoratedFragmentationStrategy = mock(FragmentationStrategy.class); - private FragmentationStrategy fragmentationStrategy; - private static Fragment PARENT_FRAGMENT; - private static Fragment OPEN_FRAGMENT; - private final FragmentRepository fragmentRepository = mock(FragmentRepository.class); - - @BeforeEach - void setUp() { - PARENT_FRAGMENT = new Fragment(new LdesFragmentIdentifier(VIEW_NAME, List.of())); - OPEN_FRAGMENT = PARENT_FRAGMENT.createChild(new FragmentPair("generatedAtTime", "someTime")); - fragmentationStrategy = new TimebasedFragmentationStrategy(decoratedFragmentationStrategy, - openFragmentProvider, ObservationRegistry.create(), - fragmentRepository); - } - - @Test - void when_MemberIsAddedToFragment_TimebasedFragmentationIsApplied() { - Member member = mock(Member.class); - when(member.id()).thenReturn("memberId"); - when(openFragmentProvider.retrieveOpenFragmentOrCreateNewFragment(PARENT_FRAGMENT)) - .thenReturn(new ImmutablePair<>(OPEN_FRAGMENT, false)); - - fragmentationStrategy.addMemberToFragment(PARENT_FRAGMENT, - member.id(), member.model(), any(Observation.class)); - - InOrder inOrder = inOrder(openFragmentProvider, fragmentRepository, - decoratedFragmentationStrategy); - inOrder.verify(openFragmentProvider, - times(1)).retrieveOpenFragmentOrCreateNewFragment(PARENT_FRAGMENT); - inOrder.verify(decoratedFragmentationStrategy, times(1)) - .addMemberToFragment(eq(OPEN_FRAGMENT), any(), any(), any(Observation.class)); - inOrder.verifyNoMoreInteractions(); - } - - @Test - void when_MemberIsAddedToFirstFragment_TimebasedFragmentationIsAppliedAndRelationIsAdded() { - Member member = mock(Member.class); - when(member.id()).thenReturn("memberId"); - when(openFragmentProvider.retrieveOpenFragmentOrCreateNewFragment(PARENT_FRAGMENT)) - .thenReturn(new ImmutablePair<>(OPEN_FRAGMENT, true)); - - fragmentationStrategy.addMemberToFragment(PARENT_FRAGMENT, - member.id(), member.model(), any(Observation.class)); - - InOrder inOrder = inOrder(openFragmentProvider, fragmentRepository, - decoratedFragmentationStrategy); - inOrder.verify(openFragmentProvider, - times(1)).retrieveOpenFragmentOrCreateNewFragment(PARENT_FRAGMENT); - inOrder.verify(fragmentRepository, - times(1)).saveFragment(PARENT_FRAGMENT); - inOrder.verify(decoratedFragmentationStrategy, times(1)) - .addMemberToFragment(eq(OPEN_FRAGMENT), any(), any(), any(Observation.class)); - inOrder.verifyNoMoreInteractions(); - } -} diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimebasedFragmentationStrategyWrapperTest.java b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimebasedFragmentationStrategyWrapperTest.java deleted file mode 100644 index 64e26cbeb8..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/TimebasedFragmentationStrategyWrapperTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased; - -import be.vlaanderen.informatievlaanderen.ldes.server.domain.model.ConfigProperties; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.FragmentationStrategy; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.springframework.context.ApplicationContext; - -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; - -class TimebasedFragmentationStrategyWrapperTest { - - private final ApplicationContext applicationContext = mock(ApplicationContext.class); - private final FragmentationStrategy fragmentationStrategy = mock(FragmentationStrategy.class); - private TimebasedFragmentationStrategyWrapper timebasedFragmentationUpdater; - - @BeforeEach - void setUp() { - timebasedFragmentationUpdater = new TimebasedFragmentationStrategyWrapper(); - } - - @Test - void when_FragmentationStrategyIsUpdated_TimebasedFragmentationStrategyIsReturned() { - ConfigProperties properties = new ConfigProperties(Map.of("memberLimit", "5")); - FragmentationStrategy decoratedFragmentationStrategy = timebasedFragmentationUpdater - .wrapFragmentationStrategy(applicationContext, fragmentationStrategy, properties); - assertTrue(decoratedFragmentationStrategy instanceof TimebasedFragmentationStrategy); - } -} \ No newline at end of file diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/services/OpenFragmentProviderTest.java b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/services/OpenFragmentProviderTest.java deleted file mode 100644 index 5f92a3796e..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/services/OpenFragmentProviderTest.java +++ /dev/null @@ -1,103 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.services; - -import be.vlaanderen.informatievlaanderen.ldes.server.domain.model.FragmentPair; -import be.vlaanderen.informatievlaanderen.ldes.server.domain.model.LdesFragmentIdentifier; -import be.vlaanderen.informatievlaanderen.ldes.server.domain.model.ViewName; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.entities.Fragment; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.repository.FragmentRepository; -import org.apache.commons.lang3.tuple.Pair; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.mockito.InOrder; - -import java.util.List; -import java.util.Optional; - -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.*; - -class OpenFragmentProviderTest { - - private final TimeBasedFragmentCreator fragmentCreator = mock(TimeBasedFragmentCreator.class); - private final FragmentRepository fragmentRepository = mock(FragmentRepository.class); - private OpenFragmentProvider openFragmentProvider; - private static Fragment PARENT_FRAGMENT; - private static final ViewName VIEW_NAME = new ViewName("collectionName", "view"); - - @BeforeEach - void setUp() { - PARENT_FRAGMENT = new Fragment(new LdesFragmentIdentifier(VIEW_NAME, List.of())); - openFragmentProvider = new OpenFragmentProvider(fragmentCreator, - fragmentRepository, 3L); - } - - @Test - @DisplayName("No existing fragment") - void when_NoFragmentExists_thenFragmentIsCreated() { - Fragment createdFragment = PARENT_FRAGMENT.createChild(new FragmentPair("Path", - "Value")); - when(fragmentRepository.retrieveOpenChildFragment(PARENT_FRAGMENT.getFragmentId())) - .thenReturn(Optional.empty()); - when(fragmentCreator.createNewFragment(PARENT_FRAGMENT)) - .thenReturn(createdFragment); - - Pair ldesFragment = openFragmentProvider - .retrieveOpenFragmentOrCreateNewFragment(PARENT_FRAGMENT); - - assertTrue(ldesFragment.getRight()); - assertEquals(createdFragment, ldesFragment.getKey()); - InOrder inOrder = inOrder(fragmentRepository, fragmentCreator); - inOrder.verify(fragmentRepository, - times(1)).retrieveOpenChildFragment(PARENT_FRAGMENT.getFragmentId()); - inOrder.verify(fragmentCreator, times(1)).createNewFragment(PARENT_FRAGMENT); - inOrder.verify(fragmentRepository, times(1)).saveFragment(createdFragment); - inOrder.verifyNoMoreInteractions(); - } - - @Test - @DisplayName("Incomplete Open Fragment") - void when_AnIncompleteOpenFragmentExists_thenFragmentIsReturned() { - Fragment existingFragment = PARENT_FRAGMENT.createChild(new FragmentPair("Path", - "Value")); - when(fragmentRepository.retrieveOpenChildFragment(PARENT_FRAGMENT.getFragmentId())) - .thenReturn(Optional.of(existingFragment)); - - Pair ldesFragment = openFragmentProvider - .retrieveOpenFragmentOrCreateNewFragment(PARENT_FRAGMENT); - - assertFalse(ldesFragment.getRight()); - assertEquals(existingFragment, ldesFragment.getKey()); - InOrder inOrder = inOrder(fragmentRepository, fragmentCreator); - inOrder.verify(fragmentRepository, - times(1)).retrieveOpenChildFragment(PARENT_FRAGMENT.getFragmentId()); - inOrder.verifyNoMoreInteractions(); - } - - @Test - @DisplayName("Complete Fragment") - void when_AFullFragmentExists_thenANewFragmentIsCreatedAndReturned() { - Fragment completeFragment = new Fragment(new LdesFragmentIdentifier( - VIEW_NAME, List.of(new FragmentPair("OldPath", - "OldValue"))), - false, 3, List.of(), null); - Fragment newFragment = PARENT_FRAGMENT.createChild(new FragmentPair("Path", - "Value")); - when(fragmentRepository.retrieveOpenChildFragment(PARENT_FRAGMENT.getFragmentId())) - .thenReturn(Optional.of(completeFragment)); - when(fragmentCreator.createNewFragment(completeFragment, PARENT_FRAGMENT)).thenReturn(newFragment); - - Pair ldesFragment = openFragmentProvider - .retrieveOpenFragmentOrCreateNewFragment(PARENT_FRAGMENT); - - assertFalse(ldesFragment.getRight()); - assertEquals(newFragment, ldesFragment.getKey()); - InOrder inOrder = inOrder(fragmentRepository, fragmentCreator); - inOrder.verify(fragmentRepository, - times(1)).retrieveOpenChildFragment(PARENT_FRAGMENT.getFragmentId()); - inOrder.verify(fragmentCreator, times(1)).createNewFragment(completeFragment, PARENT_FRAGMENT); - inOrder.verify(fragmentRepository, times(1)).saveFragment(newFragment); - inOrder.verifyNoMoreInteractions(); - } - -} diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/services/TimeBasedFragmentCreatorTest.java b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/services/TimeBasedFragmentCreatorTest.java deleted file mode 100644 index cc878a0260..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/fragmentisers/timebased/services/TimeBasedFragmentCreatorTest.java +++ /dev/null @@ -1,71 +0,0 @@ -package be.vlaanderen.informatievlaanderen.ldes.server.fragmentisers.timebased.services; - -import be.vlaanderen.informatievlaanderen.ldes.server.domain.model.FragmentPair; -import be.vlaanderen.informatievlaanderen.ldes.server.domain.model.LdesFragmentIdentifier; -import be.vlaanderen.informatievlaanderen.ldes.server.domain.model.ViewName; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.entities.Fragment; -import be.vlaanderen.informatievlaanderen.ldes.server.fragmentation.repository.FragmentRepository; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.mockito.InOrder; - -import java.util.List; - -import static be.vlaanderen.informatievlaanderen.ldes.server.domain.constants.RdfConstants.GENERATED_AT_TIME; -import static be.vlaanderen.informatievlaanderen.ldes.server.domain.constants.RdfConstants.PROV_GENERATED_AT_TIME; -import static org.apache.jena.rdf.model.ResourceFactory.createProperty; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.*; - -class TimeBasedFragmentCreatorTest { - - private static final ViewName VIEW_NAME = new ViewName("collectionName", "view"); - private TimeBasedFragmentCreator fragmentCreator; - private FragmentRepository fragmentRepository; - - @BeforeEach - void setUp() { - fragmentRepository = mock(FragmentRepository.class); - fragmentCreator = new TimeBasedFragmentCreator( - fragmentRepository, - createProperty(PROV_GENERATED_AT_TIME)); - } - - @Test - @DisplayName("Creating First Time-Based Fragment") - void when_NoFragmentExists_thenNewFragmentIsCreated() { - Fragment parentFragment = new Fragment(new LdesFragmentIdentifier(VIEW_NAME, List.of())); - - Fragment newFragment = fragmentCreator.createNewFragment(parentFragment); - - verifyAssertionsOnAttributesOfFragment(newFragment); - verifyNoInteractions(fragmentRepository); - } - - @Test - @DisplayName("Creating New Time-Based Fragment") - void when_AFragmentAlreadyExists_thenNewFragmentIsCreatedAndRelationsAreUpdated() { - Fragment parentFragment = new Fragment(new LdesFragmentIdentifier(VIEW_NAME, List.of())); - - Fragment existingFragment = new Fragment(new LdesFragmentIdentifier( - VIEW_NAME, List.of(new FragmentPair(GENERATED_AT_TIME, - "2020-12-28T09:36:37.127Z")))); - - Fragment newFragment = fragmentCreator.createNewFragment(existingFragment, parentFragment); - - verifyAssertionsOnAttributesOfFragment(newFragment); - InOrder inOrder = inOrder(fragmentRepository); - inOrder.verify(fragmentRepository, times(1)).saveFragment(existingFragment); - inOrder.verify(fragmentRepository, times(1)).saveFragment(newFragment); - inOrder.verifyNoMoreInteractions(); - } - - private void verifyAssertionsOnAttributesOfFragment(Fragment fragment) { - assertEquals("/collectionName/view?generatedAtTime", - fragment.getFragmentIdString().split("=")[0]); - assertEquals(VIEW_NAME, fragment.getViewName()); - assertTrue(fragment.getValueOfKey(GENERATED_AT_TIME).isPresent()); - } -} diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/resources/application-test.yml b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/resources/application-test.yml deleted file mode 100644 index fa9d95efbc..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/resources/application-test.yml +++ /dev/null @@ -1,10 +0,0 @@ -ldes: - collection-name: "testData" - host-name: "http://localhost:8080" - shape: "https://private-api.gipod.test-vlaanderen.be/api/v1/ldes/mobility-hindrances/shape" - member-type: "https://data.vlaanderen.be/ns/mobiliteit#Mobiliteitshinder" -view: - shape: "https://private-api.gipod.test-vlaanderen.be/api/v1/ldes/mobility-hindrances/shape" - member-limit: 5 - timestamp-path: "http://www.w3.org/ns/prov#generatedAtTime" - version-of-path: "http://purl.org/dc/terms/isVersionOf" diff --git a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/resources/example-ldes-member.nq b/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/resources/example-ldes-member.nq deleted file mode 100644 index 3fb817191c..0000000000 --- a/ldes-fragmentisers/ldes-fragmentisers-timebased/src/test/resources/example-ldes-member.nq +++ /dev/null @@ -1,17 +0,0 @@ -_:B0e0f2247f649c24c02615ba87b3edbb8 "10228622"^^ . -_:B0e0f2247f649c24c02615ba87b3edbb8 "https://gipod.vlaanderen.be"@nl-be . -_:Bdfb7e9d001c2f76fdacc91827c53be2f "MULTIPOLYGON (((151842.820425803 203601.06220622, 151858.99959723 203622.904124678, 151878.08746246 203679.213341669, 151879.996292671 203726.932968336, 151889.540225286 203843.36895352, 151876.178705062 203681.122099066, 151842.820425803 203601.06220622)), ((151822.028950614 203546.308410528, 151833.231008295 203578.047597699, 151842.820425803 203601.06220622, 151839.911732 203597.135462929, 151822.732696982 203552.279008765, 151822.028950614 203546.308410528)), ((151819.632069955 203525.973227162, 151822.028950614 203546.308410528, 151821.778318283 203545.59828506, 151819.632069955 203525.973227162)), ((151835.067861652 203332.678639158, 151835.459172022 203332.703010269, 151835.838208905 203332.803253961, 151836.190406127 203332.975517927, 151836.502228945 203333.213182158, 151836.761694184 203333.507113352, 151836.958830739 203333.846015897, 151837.086062765 203334.216865959, 151837.138500805 203334.605411978, 151837.114129694 203334.996722348, 151816.117507067 203464.794227756, 151816.017263374 203465.173264639, 151815.844999409 203465.525461861, 151815.607335177 203465.837284679, 151815.313403984 203466.096749917, 151814.974501438 203466.293886473, 151814.603651376 203466.421118499, 151814.215105358 203466.473556538, 151813.823794987 203466.449185428, 151813.444758104 203466.348941735, 151813.092560883 203466.176677769, 151819.632069955 203525.973227162, 151812.521272826 203465.645082344, 151812.32413627 203465.306179799, 151812.196904245 203464.935329737, 151812.144466205 203464.546783718, 151812.168837315 203464.155473348, 151833.165459942 203334.357967941, 151833.265703635 203333.978931058, 151833.437967601 203333.626733836, 151833.675631832 203333.314911018, 151833.969563026 203333.055445779, 151834.308465571 203332.858309223, 151834.679315633 203332.731077198, 151835.067861652 203332.678639158)))"^^ . - "2020-12-28T09:36:37.127Z"^^ . - "2630 Aartselaar, Baron van Ertbornstraat: Werfzone"^^ . - "MobilityHindranceWasImportedFromLegacy"@nl-be . - "2020-12-14T13:10:01.463Z"^^ . - "10228622"^^ . - "2020-12-14T13:48:33.083Z"^^ . - "Geen doorgang voor voetgangers"@nl-be . - "EagleBe Smartcity"^^ . - "HinderZone"@nl-be . - "Onbekend"@nl-be . -_:B6d6151daf809cfb8e19b0042133ebf90 "2021-03-27T15:00:00Z"^^ . -_:B6d6151daf809cfb8e19b0042133ebf90 "2021-01-04T06:00:00Z"^^ . - . - . \ No newline at end of file diff --git a/ldes-fragmentisers/pom.xml b/ldes-fragmentisers/pom.xml index 748bb2c76a..d199b0ca83 100644 --- a/ldes-fragmentisers/pom.xml +++ b/ldes-fragmentisers/pom.xml @@ -15,10 +15,10 @@ ldes-fragmentisers-common ldes-fragmentisers-geospatial ldes-fragmentisers-substring - ldes-fragmentisers-timebased + ldes-fragmentisers-timebased-hierarchical ldes-fragmentisers-pagination ldes-snapshot - ldes-fragmentisers-timebased-hierarchical + diff --git a/ldes-server-integration-test/pom.xml b/ldes-server-integration-test/pom.xml index 0aeb51326b..a576508f35 100644 --- a/ldes-server-integration-test/pom.xml +++ b/ldes-server-integration-test/pom.xml @@ -70,6 +70,24 @@ ${project.version} test + + be.vlaanderen.informatievlaanderen.vsds + ldes-fragmentisers-geospatial + ${project.version} + test + + + be.vlaanderen.informatievlaanderen.vsds + ldes-fragmentisers-timebased-hierarchical + ${project.version} + test + + + be.vlaanderen.informatievlaanderen.vsds + ldes-fragmentisers-substring + ${project.version} + test + be.vlaanderen.informatievlaanderen.vsds mongo-fragmentation-repository diff --git a/ldes-server-integration-test/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/FragmentationSteps.java b/ldes-server-integration-test/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/FragmentationSteps.java new file mode 100644 index 0000000000..e891275742 --- /dev/null +++ b/ldes-server-integration-test/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/FragmentationSteps.java @@ -0,0 +1,112 @@ +package be.vlaanderen.informatievlaanderen.ldes.server; + +import io.cucumber.java.en.And; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.Property; +import org.apache.jena.rdf.model.Resource; +import org.apache.jena.riot.Lang; +import org.apache.jena.riot.RDFParser; +import org.apache.jena.vocabulary.RDF; +import org.springframework.mock.web.MockHttpServletResponse; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; + +import static org.apache.jena.rdf.model.ResourceFactory.createProperty; +import static org.apache.jena.rdf.model.ResourceFactory.createResource; +import static org.awaitility.Awaitility.await; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; + +public class FragmentationSteps extends LdesServerIntegrationTest { + private static final String TREE = "https://w3id.org/tree#"; + private static final Property TREE_MEMBER = createProperty(TREE, "member"); + private Model currentFragment; + private String currentPath; + private String currentFragmentCacheControl; + + @When("I fetch the root {string} fragment of {string}") + public void iFetchTheRootFragment(String view, String collection) throws Exception { + currentPath = "/%s/%s".formatted(collection, view); + MockHttpServletResponse response = mockMvc.perform(get(currentPath).accept("text/turtle")) + .andReturn() + .getResponse(); + currentFragmentCacheControl = response.getHeader("Cache-Control"); + currentFragment = RDFParser.fromString(response.getContentAsString()).lang(Lang.TURTLE).toModel(); + } + + private void fetchFragment(String path) throws Exception { + currentPath = path; + MockHttpServletResponse response = mockMvc.perform(get(path) + .accept("text/turtle")) + .andReturn() + .getResponse(); + currentFragmentCacheControl = response.getHeader("Cache-Control"); + currentFragment = RDFParser.fromString(response.getContentAsString()).lang(Lang.TURTLE).toModel(); + } + + @And("I fetch the next fragment through the first {string}") + public void iFetchTheNextFragmentThroughTheFirst(String relation) throws Exception { + Resource relationSubj = currentFragment.listStatements(null, RDF.type, createResource(TREE + relation)) + .next().getSubject(); + + currentPath = currentFragment.listStatements(relationSubj, createProperty(TREE, "node"), (Resource) null) + .next().getObject().toString(); + + MockHttpServletResponse response = mockMvc.perform(get(currentPath).accept("text/turtle")) + .andReturn() + .getResponse(); + currentFragmentCacheControl = response.getHeader("Cache-Control"); + currentFragment = RDFParser.fromString(response.getContentAsString()).lang(Lang.TURTLE).toModel(); + } + + @Then("this fragment only has {int} {string} relation") + public void thisFragmentOnlyHasOne(int expectedRelationCount, String relation) { + await().atMost(Duration.of(20, ChronoUnit.SECONDS)).until(() -> { + fetchFragment(currentPath); + int relationCount = currentFragment.listStatements(null, RDF.type, createResource(TREE + relation)) + .toList().size(); + return relationCount == expectedRelationCount; + }); + } + + @And("this fragment is immutable") + public void thisFragmentIsImmutable() { + assertTrue(currentFragmentCacheControl.contains("immutable")); + } + + @And("this fragment contains {int} members") + public void thisFragmentContainsMembers(int expectedMemberCount) { + await().atMost(Duration.of(20, ChronoUnit.SECONDS)).until(() -> { + fetchFragment(currentPath); + return currentFragment.listObjectsOfProperty(TREE_MEMBER).toList().size() == expectedMemberCount; + }); + } + + @And("this fragment is mutable") + public void thisFragmentIsNotImmutable() { + assertFalse(currentFragmentCacheControl.contains("immutable")); + } + + @And("this fragment has no relations") + public void thisFragmentHasNoRelations() { + await().atMost(Duration.of(20, ChronoUnit.SECONDS)).until(() -> { + fetchFragment(currentPath); + return !currentFragment.listObjectsOfProperty(createProperty(TREE + "relation")).hasNext(); + }); + } + + @When("I fetch the geo-spatial fragment for tile {string} from the {string} view of {string}") + public void iFetchTheGeoSpatialFragmentForTileFromTheViewOf(String tile, String view, String collection) + throws Exception { + currentPath = "/%s/%s?tile=%s".formatted(collection, view, tile); + MockHttpServletResponse response = mockMvc.perform(get(currentPath).accept("text/turtle")) + .andReturn() + .getResponse(); + currentFragmentCacheControl = response.getHeader("Cache-Control"); + currentFragment = RDFParser.fromString(response.getContentAsString()).lang(Lang.TURTLE).toModel(); + } +} diff --git a/ldes-server-integration-test/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/LdesServerIntegrationTest.java b/ldes-server-integration-test/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/LdesServerIntegrationTest.java index 05ea3b81b8..199a0afc46 100644 --- a/ldes-server-integration-test/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/LdesServerIntegrationTest.java +++ b/ldes-server-integration-test/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/LdesServerIntegrationTest.java @@ -1,6 +1,7 @@ package be.vlaanderen.informatievlaanderen.ldes.server; import be.vlaanderen.informatievlaanderen.ldes.server.ingest.MemberEntityRepository; +import be.vlaanderen.informatievlaanderen.ldes.server.ingest.repositories.MemberRepository; import io.cucumber.spring.CucumberContextConfiguration; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -25,4 +26,7 @@ public class LdesServerIntegrationTest { @Autowired MockMvc mockMvc; + @Autowired + MemberRepository memberRepository; + } diff --git a/ldes-server-integration-test/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/LdesServerSteps.java b/ldes-server-integration-test/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/LdesServerSteps.java index cb703dbfe1..4d8ee9b71c 100644 --- a/ldes-server-integration-test/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/LdesServerSteps.java +++ b/ldes-server-integration-test/src/test/java/be/vlaanderen/informatievlaanderen/ldes/server/LdesServerSteps.java @@ -1,5 +1,7 @@ package be.vlaanderen.informatievlaanderen.ldes.server; +import io.cucumber.java.After; +import io.cucumber.java.en.And; import io.cucumber.java.en.Given; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; @@ -92,7 +94,7 @@ private Model stripGeneratedAtTimeOfModel(Model model) { (Resource) null)); } - @When("I ingest the member described in {string} the collection {string}") + @When("I ingest the data described in {string} the collection {string}") public void iIngestTheMemberDescribedInTheCollection(String memberFileName, String collectionName) throws Exception { String member = readBodyFromFile(memberFileName); @@ -173,4 +175,16 @@ public void firstFragmentOfViewContainsMembers(String view, String collection, l .toList().size() == expectedMemberCount; }); } + + @And("the LDES {string} contains {int} members") + public void theLDESContainsMembers(String collection, int expectedMemberCount) { + await().atMost(Duration.ofSeconds(20)) + .until(() -> memberRepository.getMemberStreamOfCollection(collection).count() == expectedMemberCount); + } + + @After + public void cleanup() throws Exception { + mockMvc.perform(delete("/admin/api/v1/eventstreams/mobility-hindrances")) + .andExpect(status().isOk()); + } } diff --git a/ldes-server-integration-test/src/test/resources/data/input/eventstreams/fragmentation/mobility-hindrances.by-loc.ttl b/ldes-server-integration-test/src/test/resources/data/input/eventstreams/fragmentation/mobility-hindrances.by-loc.ttl new file mode 100644 index 0000000000..1deaa4f2bd --- /dev/null +++ b/ldes-server-integration-test/src/test/resources/data/input/eventstreams/fragmentation/mobility-hindrances.by-loc.ttl @@ -0,0 +1,28 @@ +@prefix ldes: . +@prefix dcterms: . +@prefix tree: . +@prefix sh: . +@prefix server: . +@prefix xsd: . +@prefix mobility-hindrances: . +@prefix geosparql: . + +server:mobility-hindrances a ldes:EventStream ; + ldes:timestampPath dcterms:created ; + ldes:versionOfPath dcterms:isVersionOf ; + tree:view mobility-hindrances:by-loc ; + tree:shape mobility-hindrances:shape . + +mobility-hindrances:by-loc a tree:Node ; + tree:viewDescription [ + a tree:ViewDescription ; + tree:fragmentationStrategy ([ + a tree:GeospatialFragmentation; ; + tree:maxZoom "9"^^xsd:integer ; + tree:fragmentationPath geosparql:asWKT ; + ]) ; + tree:pageSize "10"^^xsd:integer ; + ] . + +mobility-hindrances:shape a sh:NodeShape ; + sh:targetClass . \ No newline at end of file diff --git a/ldes-server-integration-test/src/test/resources/data/input/eventstreams/fragmentation/mobility-hindrances.multi-view.ttl b/ldes-server-integration-test/src/test/resources/data/input/eventstreams/fragmentation/mobility-hindrances.multi-view.ttl new file mode 100644 index 0000000000..b765746589 --- /dev/null +++ b/ldes-server-integration-test/src/test/resources/data/input/eventstreams/fragmentation/mobility-hindrances.multi-view.ttl @@ -0,0 +1,36 @@ +@prefix ldes: . +@prefix dcterms: . +@prefix tree: . +@prefix sh: . +@prefix server: . +@prefix xsd: . +@prefix mobility-hindrances: . +@prefix geosparql: . + +server:mobility-hindrances a ldes:EventStream ; + ldes:timestampPath dcterms:created ; + ldes:versionOfPath dcterms:isVersionOf ; + tree:view mobility-hindrances:by-loc ; + tree:view mobility-hindrances:paged ; + tree:shape mobility-hindrances:shape . + +mobility-hindrances:by-loc a tree:Node ; + tree:viewDescription [ + a tree:ViewDescription ; + tree:fragmentationStrategy ([ + a tree:GeospatialFragmentation; ; + tree:maxZoom "9"^^xsd:integer ; + tree:fragmentationPath geosparql:asWKT ; + ]) ; + tree:pageSize "10"^^xsd:integer ; + ] . + +mobility-hindrances:paged a tree:Node ; + tree:viewDescription [ + a tree:ViewDescription ; + tree:fragmentationStrategy () ; + tree:pageSize "300"^^xsd:integer ; + ] . + +mobility-hindrances:shape a sh:NodeShape ; + sh:targetClass . \ No newline at end of file diff --git a/ldes-server-integration-test/src/test/resources/data/input/eventstreams/fragmentation/mobility-hindrances.paged.ttl b/ldes-server-integration-test/src/test/resources/data/input/eventstreams/fragmentation/mobility-hindrances.paged.ttl new file mode 100644 index 0000000000..7672743a00 --- /dev/null +++ b/ldes-server-integration-test/src/test/resources/data/input/eventstreams/fragmentation/mobility-hindrances.paged.ttl @@ -0,0 +1,23 @@ +@prefix ldes: . +@prefix dcterms: . +@prefix tree: . +@prefix sh: . +@prefix server: . +@prefix xsd: . +@prefix mobility-hindrances: . + +server:mobility-hindrances a ldes:EventStream ; + ldes:timestampPath dcterms:created ; + ldes:versionOfPath dcterms:isVersionOf ; + tree:view mobility-hindrances:paged ; + tree:shape mobility-hindrances:shape . + +mobility-hindrances:paged a tree:Node ; + tree:viewDescription [ + a tree:ViewDescription ; + tree:fragmentationStrategy () ; + tree:pageSize "300"^^xsd:integer ; + ] . + +mobility-hindrances:shape a sh:NodeShape ; + sh:targetClass . \ No newline at end of file diff --git a/ldes-server-integration-test/src/test/resources/data/input/eventstreams/mobility-hindrances_combined.ttl b/ldes-server-integration-test/src/test/resources/data/input/eventstreams/retention/mobility-hindrances_combined.ttl similarity index 100% rename from ldes-server-integration-test/src/test/resources/data/input/eventstreams/mobility-hindrances_combined.ttl rename to ldes-server-integration-test/src/test/resources/data/input/eventstreams/retention/mobility-hindrances_combined.ttl diff --git a/ldes-server-integration-test/src/test/resources/data/input/eventstreams/mobility-hindrances_pointintime.ttl b/ldes-server-integration-test/src/test/resources/data/input/eventstreams/retention/mobility-hindrances_pointintime.ttl similarity index 100% rename from ldes-server-integration-test/src/test/resources/data/input/eventstreams/mobility-hindrances_pointintime.ttl rename to ldes-server-integration-test/src/test/resources/data/input/eventstreams/retention/mobility-hindrances_pointintime.ttl diff --git a/ldes-server-integration-test/src/test/resources/data/input/eventstreams/mobility-hindrances_timebased.ttl b/ldes-server-integration-test/src/test/resources/data/input/eventstreams/retention/mobility-hindrances_timebased.ttl similarity index 100% rename from ldes-server-integration-test/src/test/resources/data/input/eventstreams/mobility-hindrances_timebased.ttl rename to ldes-server-integration-test/src/test/resources/data/input/eventstreams/retention/mobility-hindrances_timebased.ttl diff --git a/ldes-server-integration-test/src/test/resources/data/input/eventstreams/mobility-hindrances_versionbased.ttl b/ldes-server-integration-test/src/test/resources/data/input/eventstreams/retention/mobility-hindrances_versionbased.ttl similarity index 100% rename from ldes-server-integration-test/src/test/resources/data/input/eventstreams/mobility-hindrances_versionbased.ttl rename to ldes-server-integration-test/src/test/resources/data/input/eventstreams/retention/mobility-hindrances_versionbased.ttl diff --git a/ldes-server-integration-test/src/test/resources/data/input/members/member_template.ttl b/ldes-server-integration-test/src/test/resources/data/input/members/member_template.ttl index 5c78bf2a89..c3aa394d33 100644 --- a/ldes-server-integration-test/src/test/resources/data/input/members/member_template.ttl +++ b/ldes-server-integration-test/src/test/resources/data/input/members/member_template.ttl @@ -1,9 +1,11 @@ @prefix dc: . @prefix prov: . @prefix xsd: . -@prefix rdf: . +@prefix rdf: . +@prefix geosparql: . dc:isVersionOf ; rdf:type ; + geosparql:asWKT "POLYGON ((3.7337472847142124 51.04745170597559, 4.359276660355135 50.851907920816956, 4.711285586572245 50.84364854093491, 4.4020885567877315 51.214619167436666, 3.7337472847142124 51.04745170597559))"^^ ; prov:generatedAtTime "DATETIME"^^xsd:dateTime . \ No newline at end of file diff --git a/ldes-server-integration-test/src/test/resources/features/fragmentation.feature b/ldes-server-integration-test/src/test/resources/features/fragmentation.feature new file mode 100644 index 0000000000..1a2a94578d --- /dev/null +++ b/ldes-server-integration-test/src/test/resources/features/fragmentation.feature @@ -0,0 +1,51 @@ +Feature: LDES Server Fragmentation + + @pagination + Scenario: Server Can Paginate an LDES + Given I create the eventstream "data/input/eventstreams/fragmentation/mobility-hindrances.paged.ttl" + When I ingest 617 members to the collection "mobility-hindrances" + Then the LDES "mobility-hindrances" contains 617 members + When I fetch the root "paged" fragment of "mobility-hindrances" + And I fetch the next fragment through the first "Relation" + Then this fragment only has 1 "Relation" relation + And this fragment is immutable + When I fetch the next fragment through the first "Relation" + Then this fragment only has 1 "Relation" relation + And this fragment is immutable + When I fetch the next fragment through the first "Relation" + And this fragment contains 17 members + And this fragment is mutable + And this fragment has no relations + + @geospatial + Scenario: Server Can Multi-level Fragment an LDES + Given I create the eventstream "data/input/eventstreams/fragmentation/mobility-hindrances.by-loc.ttl" + And I ingest 6 members to the collection "mobility-hindrances" + And the LDES "mobility-hindrances" contains 6 members + When I fetch the root "by-loc" fragment of "mobility-hindrances" + Then this fragment only has 1 "Relation" relation + When I fetch the next fragment through the first "Relation" + Then this fragment only has 3 "GeospatiallyContainsRelation" relation + And this fragment is mutable + When I fetch the geo-spatial fragment for tile '9/262/171' from the "by-loc" view of "mobility-hindrances" + Then this fragment only has 1 "Relation" relation + When I fetch the next fragment through the first "Relation" + And this fragment contains 6 members + When I fetch the geo-spatial fragment for tile '9/262/170' from the "by-loc" view of "mobility-hindrances" + Then this fragment only has 1 "Relation" relation + When I fetch the next fragment through the first "Relation" + And this fragment contains 6 members + When I fetch the geo-spatial fragment for tile '9/261/171' from the "by-loc" view of "mobility-hindrances" + Then this fragment only has 1 "Relation" relation + When I fetch the next fragment through the first "Relation" + And this fragment contains 6 members + + @multi-view + Scenario: Server Allows Multiple Views in an LDES + Given I create the eventstream "data/input/eventstreams/fragmentation/mobility-hindrances.by-loc.ttl" + And I ingest 6 members to the collection "mobility-hindrances" + When I fetch the root "by-loc" fragment of "mobility-hindrances" + And I fetch the next fragment through the first "Relation" + Then this fragment only has 3 "GeospatiallyContainsRelation" relation + When I fetch the root "by-loc" fragment of "mobility-hindrances" + Then this fragment only has 1 "Relation" relation \ No newline at end of file diff --git a/ldes-server-integration-test/src/test/resources/features/ingest_different_mime_type.feature b/ldes-server-integration-test/src/test/resources/features/ingest_different_mime_type.feature index 5aa6571c82..dd88b781d6 100644 --- a/ldes-server-integration-test/src/test/resources/features/ingest_different_mime_type.feature +++ b/ldes-server-integration-test/src/test/resources/features/ingest_different_mime_type.feature @@ -2,10 +2,10 @@ Feature: The LDES server supports different mime types for ingestion Scenario: Given I create the eventstream "data/input/eventstreams/mobility-hindrances_paginated_1500.ttl" - When I ingest the member described in "data/input/members/member_turtle.ttl" the collection "mobility-hindrances" - And I ingest the member described in "data/input/members/member_nquads.nq" the collection "mobility-hindrances" - And I ingest the member described in "data/input/members/member_ntriples.nt" the collection "mobility-hindrances" - And I ingest the member described in "data/input/members/member_jsonld.jsonld" the collection "mobility-hindrances" + When I ingest the data described in "data/input/members/member_turtle.ttl" the collection "mobility-hindrances" + And I ingest the data described in "data/input/members/member_nquads.nq" the collection "mobility-hindrances" + And I ingest the data described in "data/input/members/member_ntriples.nt" the collection "mobility-hindrances" + And I ingest the data described in "data/input/members/member_jsonld.jsonld" the collection "mobility-hindrances" Then I can fetch the TreeNode "/mobility-hindrances/paged?pageNumber=1" and it contains 4 members and the expected response is equal to "data/output/treenode_different_ingest_content_type_pageNumber_1.ttl" And I delete the eventstream "mobility-hindrances" diff --git a/ldes-server-integration-test/src/test/resources/features/retention.feature b/ldes-server-integration-test/src/test/resources/features/retention.feature index d16f9b1c34..161ab0a18b 100644 --- a/ldes-server-integration-test/src/test/resources/features/retention.feature +++ b/ldes-server-integration-test/src/test/resources/features/retention.feature @@ -2,33 +2,29 @@ Feature: LDES Server Retention @time-based Scenario: Server provides timebased retention - Given I create the eventstream "data/input/eventstreams/mobility-hindrances_timebased.ttl" + Given I create the eventstream "data/input/eventstreams/retention/mobility-hindrances_timebased.ttl" When I ingest 30 members to the collection "mobility-hindrances" Then the first fragment of the "paged" view in collection "mobility-hindrances" contains 30 members # Since all added members' timestamp values equal to their ingestion date, they should be removed after 15 seconds Then the first fragment of the "paged" view in collection "mobility-hindrances" contains 0 members - And I delete the eventstream "mobility-hindrances" @version-based Scenario: Server provides version retention - Given I create the eventstream "data/input/eventstreams/mobility-hindrances_versionbased.ttl" + Given I create the eventstream "data/input/eventstreams/retention/mobility-hindrances_versionbased.ttl" When I ingest 30 members to the collection "mobility-hindrances" # Since all added members belong to the same version, only 10 are kept as defined by the retention policy Then the first fragment of the "paged" view in collection "mobility-hindrances" contains 10 members - And I delete the eventstream "mobility-hindrances" @point-in-time Scenario: Server provides point in time retention - Given I create the eventstream "data/input/eventstreams/mobility-hindrances_pointintime.ttl" + Given I create the eventstream "data/input/eventstreams/retention/mobility-hindrances_pointintime.ttl" When I ingest 30 members to the collection "mobility-hindrances" # Since all added members have a timestamp after the set point in time, all members are retained Then the first fragment of the "paged" view in collection "mobility-hindrances" contains 30 members - And I delete the eventstream "mobility-hindrances" @combined @version-based-and-point-in-time Scenario: Server combines multiple retention policies - Given I create the eventstream "data/input/eventstreams/mobility-hindrances_combined.ttl" + Given I create the eventstream "data/input/eventstreams/retention/mobility-hindrances_combined.ttl" When I ingest 30 members to the collection "mobility-hindrances" # With the version based and timebased retention combined, only 5 members will remain even if they are more than 5s ago - Then the first fragment of the "paged" view in collection "mobility-hindrances" contains 5 members - And I delete the eventstream "mobility-hindrances" \ No newline at end of file + Then the first fragment of the "paged" view in collection "mobility-hindrances" contains 5 members \ No newline at end of file