Skip to content

Commit

Permalink
Feature: VSDSPUB-349: Add Gone status to soft deleted fragments
Browse files Browse the repository at this point in the history
  • Loading branch information
WLefever-Cegeka committed Nov 17, 2022
1 parent 1ccef6e commit 4ac3880
Show file tree
Hide file tree
Showing 17 changed files with 92 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package be.vlaanderen.informatievlaanderen.ldes.server.domain.exceptions;

public class DeletedFragmentException extends RuntimeException {
private final String fragmentId;

public DeletedFragmentException(String fragmentId) {
super();
this.fragmentId = fragmentId;
}

@Override
public String getMessage() {
return "Fragment with following identifier has been deleted: " + fragmentId;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@ public void setSoftDeleted(boolean softDeleted) {
this.fragmentInfo.setSoftDeleted(softDeleted);
}

public void setSoftDeleted(boolean softDeleted) {
this.fragmentInfo.setSoftDeleted(softDeleted);
}

public boolean isImmutable() {
return this.fragmentInfo.getImmutable();
}
Expand All @@ -75,4 +71,8 @@ public LdesFragment createChild(FragmentPair fragmentPair) {
public void removeRelation(TreeRelation treeRelation) {
relations.remove(treeRelation);
}

public boolean isSoftDeleted() {
return this.getFragmentInfo().getSoftDeleted();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Optional<LdesFragment> retrieveMutableFragment(String viewName,

Optional<LdesFragment> retrieveRootFragment(String viewName);

Stream<LdesFragment> retrieveImmutableFragmentsOfView(String viewName);
Stream<LdesFragment> retrieveNonDeletedImmutableFragmentsOfView(String viewName);

Optional<LdesFragment> retrieveNonDeletedChildFragment(String viewName,
List<FragmentPair> fragmentPairList);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package be.vlaanderen.informatievlaanderen.ldes.server.domain.ldesfragment.services;

import be.vlaanderen.informatievlaanderen.ldes.server.domain.config.LdesConfig;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.exceptions.DeletedFragmentException;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.exceptions.MissingFragmentException;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.ldesfragment.entities.LdesFragment;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.ldesfragment.repository.LdesFragmentRepository;
Expand All @@ -22,12 +23,16 @@ public FragmentFetchServiceImpl(LdesConfig ldesConfig,

@Override
public LdesFragment getFragment(LdesFragmentRequest ldesFragmentRequest) {
return ldesFragmentRepository
LdesFragment ldesFragment = ldesFragmentRepository
.retrieveFragment(ldesFragmentRequest)
.orElseThrow(
() -> new MissingFragmentException(

ldesConfig.getHostName() + new FragmentInfo(ldesFragmentRequest.viewName(),
ldesFragmentRequest.fragmentPairs()).generateFragmentId()));
if (ldesFragment.isSoftDeleted())
throw new DeletedFragmentException(
ldesConfig.getHostName() + new FragmentInfo(ldesFragmentRequest.viewName(),
ldesFragmentRequest.fragmentPairs()).generateFragmentId());
return ldesFragment;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public TreeNodeRemoverImpl(LdesFragmentRepository ldesFragmentRepository,
public void removeTreeNodes() {
retentionPolicyMap.forEach((view, retentionPolicies) -> {
List<LdesFragment> ldesFragments = ldesFragmentRepository
.retrieveImmutableFragmentsOfView(view)
.retrieveNonDeletedImmutableFragmentsOfView(view)
.filter(ldesFragment -> retentionPolicies
.stream()
.allMatch(retentionPolicy -> retentionPolicy.matchesPolicy(ldesFragment)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,6 @@ public void setSoftDeleted(Boolean softDeleted) {
this.softDeleted = softDeleted;
}

public Boolean getSoftDeleted() {
return softDeleted;
}

public void setSoftDeleted(Boolean softDeleted) {
this.softDeleted = softDeleted;
}

public FragmentInfo createChild(FragmentPair fragmentPair) {
ArrayList<FragmentPair> childFragmentPairs = new ArrayList<>(this.fragmentPairs.stream().toList());
childFragmentPairs.add(fragmentPair);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public TreeMemberRemoverImpl(MemberReferencesRepository memberReferencesReposito
public void tryRemovingMember(String memberId) {
if (!memberReferencesRepository.hasMemberReferences(memberId)) {
memberRepository.deleteMember(memberId);
memberReferencesRepository.deleteMemberReference(memberId);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public interface MemberReferencesRepository {

boolean hasMemberReferences(final String memberId);

void deleteMemberReference(String memberId);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package be.vlaanderen.informatievlaanderen.ldes.server.domain.ldesfragment.services;

import be.vlaanderen.informatievlaanderen.ldes.server.domain.config.LdesConfig;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.exceptions.DeletedFragmentException;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.exceptions.MissingFragmentException;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.ldesfragment.entities.LdesFragment;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.ldesfragment.repository.LdesFragmentRepository;
Expand All @@ -20,24 +21,18 @@

class FragmentFetchServiceImplTest {

private static final String COLLECTION_NAME = "exampleData";

private static final String VIEW_NAME = "view";

private static final String HOSTNAME = "http://localhost:8089/";
private static final String FRAGMENTATION_VALUE_1 = "2020-12-28T09:36:09.72Z";
private static final String FRAGMENT_ID_1 = HOSTNAME + "/" + COLLECTION_NAME + "/" + VIEW_NAME + "?generatedAtTime="
+
FRAGMENTATION_VALUE_1;
private static final FragmentInfo FRAGMENT_INFO = new FragmentInfo(
VIEW_NAME, List.of(new FragmentPair(GENERATED_AT_TIME, FRAGMENTATION_VALUE_1)));

private final LdesFragmentRepository ldesFragmentRepository = mock(LdesFragmentRepository.class);
private static FragmentInfo FRAGMENT_INFO;

private LdesFragmentRepository ldesFragmentRepository;
private FragmentFetchService fragmentFetchService;

@BeforeEach
void setUp() {
FRAGMENT_INFO = new FragmentInfo(
VIEW_NAME, List.of(new FragmentPair(GENERATED_AT_TIME, FRAGMENTATION_VALUE_1)));
ldesFragmentRepository = mock(LdesFragmentRepository.class);
LdesConfig ldesConfig = new LdesConfig();
ldesConfig.setHostName("http://localhost:8089");
fragmentFetchService = new FragmentFetchServiceImpl(ldesConfig,
Expand All @@ -58,6 +53,21 @@ void when_getFragment_WhenNoFragmentExists_ThenMissingFragmentExceptionIsThrown(
missingFragmentException.getMessage());
}

@Test
void when_getFragment_WhenFragmentIsDeleted_ThenDeletedFragmentExceptionIsThrown() {
LdesFragment ldesFragment = new LdesFragment(FRAGMENT_INFO);
ldesFragment.setSoftDeleted(true);
LdesFragmentRequest ldesFragmentRequest = new LdesFragmentRequest(VIEW_NAME,
List.of(new FragmentPair(GENERATED_AT_TIME, FRAGMENTATION_VALUE_1)));
when(ldesFragmentRepository.retrieveFragment(ldesFragmentRequest)).thenReturn(Optional.of(ldesFragment));

DeletedFragmentException deletedFragmentException = assertThrows(DeletedFragmentException.class,
() -> fragmentFetchService.getFragment(ldesFragmentRequest));
assertEquals(
"Fragment with following identifier has been deleted: http://localhost:8089/view?generatedAtTime=2020-12-28T09:36:09.72Z",
deletedFragmentException.getMessage());
}

@Test
void when_getFragment_WhenExactFragmentExists_ThenReturnThatFragment() {
LdesFragment ldesFragment = new LdesFragment(FRAGMENT_INFO);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ class TreeNodeRemoverImplTest {
void when_NodeIsImmutableAndSatisfiesRetentionPoliciesOfView_NodeCanBeSoftDeleted() {
LdesFragment notReadyToDeleteFragment = notReadyToDeleteFragment();
LdesFragment readyToDeleteFragment = readyToDeleteFragment();
when(fragmentRepository.retrieveImmutableFragmentsOfView("view"))
when(fragmentRepository.retrieveNonDeletedImmutableFragmentsOfView("view"))
.thenReturn(Stream.of(notReadyToDeleteFragment, readyToDeleteFragment));

treeNodeRemover.removeTreeNodes();

verify(fragmentRepository, times(1)).retrieveImmutableFragmentsOfView("view");
verify(fragmentRepository, times(1)).retrieveNonDeletedImmutableFragmentsOfView("view");
verify(fragmentRepository, times(1)).saveFragment(readyToDeleteFragment);
assertTrue(readyToDeleteFragment.getFragmentInfo().getSoftDeleted());
verifyNoMoreInteractions(fragmentRepository);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ void when_memberHasNoReferences_ItCanBeDeleted() {
treeMemberRemover.tryRemovingMember("memberId");

verify(memberRepository, times(1)).deleteMember("memberId");
verify(memberReferencesRepository, times(1)).deleteMemberReference("memberId");
}

@Test
Expand All @@ -32,6 +33,8 @@ void when_memberHasReferences_ItCanNotBeDeleted() {
treeMemberRemover.tryRemovingMember("memberId");

verifyNoInteractions(memberRepository);
verify(memberReferencesRepository, times(1)).hasMemberReferences("memberId");
verifyNoMoreInteractions(memberReferencesRepository);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ public Optional<LdesFragment> retrieveRootFragment(String viewName) {
}

@Override
public Stream<LdesFragment> retrieveImmutableFragmentsOfView(String viewName) {
public Stream<LdesFragment> retrieveNonDeletedImmutableFragmentsOfView(String viewName) {
return repository
.findAllByImmutableAndViewName(true, viewName)
.findAllByImmutableAndSoftDeletedAndViewName(true, false, viewName)
.stream()
.map(LdesFragmentEntity::toLdesFragment);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,9 @@ public synchronized boolean hasMemberReferences(String memberId) {
.map(MemberReferencesEntity::hasMemberReferences)
.orElseThrow(() -> new MemberNotFoundException(memberId));
}

@Override
public synchronized void deleteMemberReference(String memberId) {
repository.deleteById(memberId);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,8 @@ Optional<LdesFragmentEntity> findLdesFragmentEntityByRootAndViewName(
List<LdesFragmentEntity> findAllByImmutableAndViewName(
Boolean immutable, String viewName);

List<LdesFragmentEntity> findAllByImmutableAndSoftDeletedAndViewName(Boolean immutable, Boolean softDeleted,
String viewName);

List<LdesFragmentEntity> findAllBySoftDeletedAndViewName(Boolean softDeleted, String viewName);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package be.vlaanderen.informatievlaanderen.ldes.server.rest.exceptionhandling;

import be.vlaanderen.informatievlaanderen.ldes.server.domain.exceptions.DeletedFragmentException;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.exceptions.MissingFragmentException;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.exceptions.RdfFormatException;
import org.springframework.http.HttpHeaders;
Expand All @@ -22,6 +23,14 @@ protected ResponseEntity<Object> handleMissingFragmentException(
new HttpHeaders(), HttpStatus.NOT_FOUND, request);
}

@ExceptionHandler(value = { DeletedFragmentException.class })
protected ResponseEntity<Object> handleDeletedFragmentException(
RuntimeException ex, WebRequest request) {
String bodyOfResponse = ex.getMessage();
return handleExceptionInternal(ex, bodyOfResponse,
new HttpHeaders(), HttpStatus.GONE, request);
}

@ExceptionHandler(value = { RdfFormatException.class })
protected ResponseEntity<Object> handleRdfFormatException(
RuntimeException ex, WebRequest request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import be.vlaanderen.informatievlaanderen.ldes.server.domain.constants.RdfConstants;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.converter.PrefixAdder;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.converter.PrefixAdderImpl;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.exceptions.DeletedFragmentException;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.exceptions.MissingFragmentException;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.ldesfragment.entities.LdesFragment;
import be.vlaanderen.informatievlaanderen.ldes.server.domain.ldesfragment.services.FragmentFetchService;
Expand Down Expand Up @@ -138,6 +139,21 @@ void when_GETRequestButMissingFragmentExceptionIsThrown_NotFoundIsReturned()
resultActions.andReturn().getResponse().getContentAsString());
}

@Test
void when_GETRequestButDeletedFragmentExceptionIsThrown_NotFoundIsReturned()
throws Exception {

LdesFragmentRequest ldesFragmentRequest = new LdesFragmentRequest(VIEW_NAME,
List.of());
when(fragmentFetchService.getFragment(ldesFragmentRequest))
.thenThrow(new DeletedFragmentException("fragmentId"));

ResultActions resultActions = mockMvc.perform(get("/view").accept("application/n-quads")).andDo(print())
.andExpect(status().isGone());
assertEquals("Fragment with following identifier has been deleted: fragmentId",
resultActions.andReturn().getResponse().getContentAsString());
}

@Test
@DisplayName("Requesting using another collection name returns 404")
void when_GETRequestIsPerformedOnOtherCollectionName_ResponseIs404() throws Exception {
Expand Down

0 comments on commit 4ac3880

Please sign in to comment.