Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/fix-for-async-validations' into …
Browse files Browse the repository at this point in the history
…get-entity-info-as-command

# Conflicts:
#	src/main/java/edu/stanford/protege/gateway/history/EntityHistoryService.java
  • Loading branch information
alexsilaghi committed Jan 18, 2025
2 parents 6f6c000 + 0c53ce8 commit e84348a
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 48 deletions.
13 changes: 12 additions & 1 deletion src/main/java/edu/stanford/protege/gateway/OwlEntityService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import edu.stanford.protege.gateway.linearization.EntityLinearizationService;
import edu.stanford.protege.gateway.ontology.OntologyService;
import edu.stanford.protege.gateway.postcoordination.EntityPostCoordinationService;
import edu.stanford.protege.gateway.validators.ValidatorService;
import edu.stanford.protege.webprotege.common.ChangeRequestId;
import edu.stanford.protege.webprotege.common.EventId;
import edu.stanford.protege.webprotege.common.ProjectId;
Expand Down Expand Up @@ -41,20 +42,26 @@ public class OwlEntityService {
@Value("${icatx.formId}")
private String formId;

private final ValidatorService validatorService;


public OwlEntityService(EntityLinearizationService entityLinearizationService,
EntityPostCoordinationService entityPostCoordinationService,
EntityHistoryService entityHistoryService,
@Nonnull EventDispatcher eventDispatcher,
OntologyService ontologyService) {
OntologyService ontologyService,
ValidatorService validatorService) {
this.entityLinearizationService = entityLinearizationService;
this.entityPostCoordinationService = entityPostCoordinationService;
this.ontologyService = ontologyService;
this.eventDispatcher = eventDispatcher;
this.entityHistoryService = entityHistoryService;
this.validatorService = validatorService;
}

public OWLEntityDto getEntityInfo(String entityIri, String projectId) {
validatorService.validateProjectId(projectId);
validatorService.validateEntityExists(projectId, entityIri);
return getEntityInfo(entityIri, projectId, SecurityContextHelper.getExecutionContext());
}

Expand Down Expand Up @@ -96,6 +103,8 @@ public OWLEntityDto getEntityInfo(String entityIri, String projectId, ExecutionC
}

public List<String> getEntityChildren(String entityIRI, String projectId) {
validatorService.validateProjectId(projectId);
validatorService.validateEntityExists(projectId, entityIRI);
CompletableFuture<List<String>> entityChildren = ontologyService.getEntityChildren(entityIRI, projectId);

try {
Expand All @@ -107,6 +116,7 @@ public List<String> getEntityChildren(String entityIRI, String projectId) {
}

public String createClassEntity(String projectId, CreateEntityDto createEntityDto) {
validatorService.validateCreateEntityRequest(projectId, createEntityDto);
CompletableFuture<String> newCreatedEntityIri = ontologyService.createClassEntity(projectId, createEntityDto);
try {
return newCreatedEntityIri.get();
Expand Down Expand Up @@ -162,6 +172,7 @@ public OWLEntityDto updateEntity(OWLEntityDto owlEntityDto, String existingProje
}

private void validateEntityUpdate(OWLEntityDto owlEntityDto, String existingProjectId, String callerHash) {

callerVersionMatchesLatestVersion(owlEntityDto, existingProjectId, callerHash);
entityIsNotItsOwnParent(owlEntityDto);
linearizationParentsAreOnlyDirectParents(owlEntityDto, existingProjectId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ public CompletableFuture<LocalDateTime> getEntityLatestChangeTime(String project

@Async
public CompletableFuture<LocalDateTime> getEntityLatestChangeTime(String projectId, String entityIri, ExecutionContext executionContext) {
validatorService.validateProjectId(projectId);
validatorService.validateEntityExists(projectId, entityIri);
return entityHistorySummaryExecutor.execute(new GetEntityHistorySummaryRequest(projectId, entityIri), executionContext)
.thenApply(response -> {
if (response.entityHistorySummary() != null && response.entityHistorySummary().changes() != null && response.entityHistorySummary().changes().size() > 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import edu.stanford.protege.gateway.config.ApplicationBeans;
import edu.stanford.protege.gateway.dto.*;
import edu.stanford.protege.gateway.ontology.commands.*;
import edu.stanford.protege.gateway.validators.ValidatorService;
import edu.stanford.protege.webprotege.common.ChangeRequestId;
import edu.stanford.protege.webprotege.common.ProjectId;
import edu.stanford.protege.webprotege.ipc.CommandExecutor;
Expand All @@ -33,7 +32,6 @@ public class OntologyService {

private final static Logger LOGGER = LoggerFactory.getLogger(OntologyService.class);

private final ValidatorService validatorService;
private final CommandExecutor<GetClassAncestorsRequest, GetClassAncestorsResponse> ancestorsExecutor;
private final CommandExecutor<GetLogicalDefinitionsRequest, GetLogicalDefinitionsResponse> logicalDefinitionExecutor;
private final CommandExecutor<GetEntityFormAsJsonRequest, GetEntityFormAsJsonResponse> formDataExecutor;
Expand All @@ -47,7 +45,7 @@ public class OntologyService {
private final CommandExecutor<GetEntityCommentsRequest, GetEntityCommentsResponse> entityDiscussionExecutor;


public OntologyService(ValidatorService validatorService, CommandExecutor<GetClassAncestorsRequest, GetClassAncestorsResponse> ancestorsExecutor,
public OntologyService(CommandExecutor<GetClassAncestorsRequest, GetClassAncestorsResponse> ancestorsExecutor,
CommandExecutor<GetLogicalDefinitionsRequest, GetLogicalDefinitionsResponse> logicalDefinitionExecutor,
CommandExecutor<GetEntityFormAsJsonRequest, GetEntityFormAsJsonResponse> formDataExecutor,
CommandExecutor<GetEntityChildrenRequest, GetEntityChildrenResponse> entityChildrenExecutor,
Expand All @@ -57,7 +55,6 @@ public OntologyService(ValidatorService validatorService, CommandExecutor<GetCla
CommandExecutor<UpdateLogicalDefinitionsRequest, UpdateLogicalDefinitionsResponse> updateLogicalDefinitionExecutor,
CommandExecutor<ChangeEntityParentsRequest, ChangeEntityParentsResponse> updateParentsExecutor,
CommandExecutor<SetEntityFormDataFromJsonRequest, SetEntityFormDataFromJsonResponse> updateLanguageTermsExecutor) {
this.validatorService = validatorService;
this.ancestorsExecutor = ancestorsExecutor;
this.logicalDefinitionExecutor = logicalDefinitionExecutor;
this.formDataExecutor = formDataExecutor;
Expand All @@ -71,17 +68,14 @@ public OntologyService(ValidatorService validatorService, CommandExecutor<GetCla
}



@Async
public CompletableFuture<List<String>> getEntityParents(String entityIri, String projectId) {
return getEntityParents(entityIri, projectId, SecurityContextHelper.getExecutionContext());
}

@Async
public CompletableFuture<List<String>> getEntityParents(String entityIri, String projectId, ExecutionContext executionContext) {
validatorService.validateProjectId(projectId);
validatorService.validateEntityExists(projectId,entityIri);
return ancestorsExecutor.execute(new GetClassAncestorsRequest(IRI.create(entityIri), ProjectId.valueOf(projectId)),executionContext)
return ancestorsExecutor.execute(new GetClassAncestorsRequest(IRI.create(entityIri), ProjectId.valueOf(projectId)), executionContext)
.thenApply(response ->
response.getAncestorClassHierarchy().getChildren().stream().map(child -> child.getNode().getEntity().getIRI().toString())
.sorted()
Expand All @@ -93,6 +87,7 @@ public CompletableFuture<List<String>> getEntityParents(String entityIri, String
public CompletableFuture<EntityLogicalConditionsWrapper> getEntityLogicalConditions(String entityIri, String projectId) {
return getEntityLogicalConditions(entityIri, projectId, SecurityContextHelper.getExecutionContext());
}

@Async
public CompletableFuture<EntityLogicalConditionsWrapper> getEntityLogicalConditions(String entityIri, String projectId, ExecutionContext executionContext) {
return logicalDefinitionExecutor.execute(new GetLogicalDefinitionsRequest(ProjectId.valueOf(projectId), new OWLClassImpl(IRI.create(entityIri))), executionContext)
Expand All @@ -105,7 +100,7 @@ public CompletableFuture<EntityLogicalConditionsWrapper> getEntityLogicalConditi
}

@Async
public CompletableFuture<EntityLanguageTerms> getEntityLanguageTerms(String entityIri, String projectId, String formId){
public CompletableFuture<EntityLanguageTerms> getEntityLanguageTerms(String entityIri, String projectId, String formId) {
return getEntityLanguageTerms(entityIri, projectId, formId, SecurityContextHelper.getExecutionContext());
}

Expand Down Expand Up @@ -169,8 +164,6 @@ public void updateLanguageTerms(String entityIri, String projectId, String formI
}

public CompletableFuture<List<String>> getEntityChildren(String entityIri, String projectId) {
validatorService.validateProjectId(projectId);
validatorService.validateEntityExists(projectId, entityIri);
return entityChildrenExecutor.execute(GetEntityChildrenRequest.create(IRI.create(entityIri), ProjectId.valueOf(projectId)), SecurityContextHelper.getExecutionContext())
.thenApply(
response -> response.childrenIris()
Expand All @@ -181,9 +174,7 @@ public CompletableFuture<List<String>> getEntityChildren(String entityIri, Strin
}



public CompletableFuture<String> createClassEntity(String projectId, CreateEntityDto createEntityDto) {
validatorService.validateCreateEntityRequest(projectId, createEntityDto);
return createClassEntityExecutor.execute(
CreateClassesFromApiRequest.create(
ChangeRequestId.generate(),
Expand Down Expand Up @@ -213,5 +204,4 @@ public CompletableFuture<EntityComments> getEntityDiscussionThreads(String entit
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.semanticweb.owlapi.model.IRI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.text.MessageFormat;
Expand Down Expand Up @@ -43,11 +44,13 @@ public void validateCreateEntityRequest(String projectId, CreateEntityDto create
validateEntityParents(projectId, createEntityDto.parent());
}

@Async
private CompletableFuture<Boolean> isExistingProject(String projectId) {
return isExistingProjectExecutor.execute(GetIsExistingProjectRequest.create(ProjectId.valueOf(projectId)), SecurityContextHelper.getExecutionContext())
.thenApply(GetIsExistingProjectResponse::isExistingProject);
}

@Async
private CompletableFuture<Set<String>> getExistingEntities(String projectId, String entity) {
var entityIri = IRI.create(entity);
return filterExistingEntitiesExecutor.execute(FilterExistingEntitiesRequest.create(ProjectId.valueOf(projectId), ImmutableSet.of(entityIri)), SecurityContextHelper.getExecutionContext())
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ logging:
root: DEBUG

icatx:
formId: 0612d01f-a60f-4fe7-8421-d404915685d7
formId: 013d9d4a-9dac-4d2f-aa52-2a40fad73b77

springdoc:
swagger-ui:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
import edu.stanford.protege.gateway.linearization.EntityLinearizationService;
import edu.stanford.protege.gateway.ontology.OntologyService;
import edu.stanford.protege.gateway.postcoordination.EntityPostCoordinationService;
import edu.stanford.protege.gateway.validators.ValidatorService;
import edu.stanford.protege.webprotege.common.ProjectId;
import edu.stanford.protege.webprotege.ipc.EventDispatcher;
import edu.stanford.protege.webprotege.ipc.ExecutionContext;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand Down Expand Up @@ -53,14 +53,16 @@ public class OwlEntityServiceTest {
private EventDispatcher eventDispatcher;
@Mock
EntityLogicalConditionsWrapper entityLogicalDefinition;
@Mock
ValidatorService validatorService;

private OwlEntityService service;

private final String existingProjectId = "b717d9a3-f265-46f5-bd15-9f1cf4b132c8";

private final LocalDateTime latestUpdate = LocalDateTime.of(2024, 1, 1, 1, 1);
private final LocalDateTime latestUpdate = LocalDateTime.of(2024, 1, 1, 1, 1);

private final String eTag = Hashing.sha256().hashString(latestUpdate.toString(), StandardCharsets.UTF_8).toString();
private final String eTag = Hashing.sha256().hashString(latestUpdate.toString(), StandardCharsets.UTF_8).toString();

@BeforeEach
public void setUp() throws IOException {
Expand All @@ -69,7 +71,7 @@ public void setUp() throws IOException {
.setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));
File specFile = new File("src/test/resources/dummyOwlEntityDto.json");
dto = objectMapper.readValue(specFile, OWLEntityDto.class);
service = new OwlEntityService(entityLinearizationService, entityPostCoordinationService,entityHistoryService,eventDispatcher, entityOntologyService);
service = new OwlEntityService(entityLinearizationService, entityPostCoordinationService, entityHistoryService, eventDispatcher, entityOntologyService, validatorService);

}

Expand All @@ -86,7 +88,7 @@ private void initializeGetMocks() {


@Test
public void GIVEN_entityWithLinearizationParentDifferentThanExistingParents_WHEN_update_THEN_validationIsThrown(){
public void GIVEN_entityWithLinearizationParentDifferentThanExistingParents_WHEN_update_THEN_validationIsThrown() {
when(entityHistoryService.getEntityLatestChangeTime(eq(existingProjectId), eq(dto.entityIRI()))).thenReturn(
CompletableFuture.supplyAsync(() -> LocalDateTime.of(2024, 1, 1, 1, 1))
);
Expand All @@ -100,9 +102,9 @@ public void GIVEN_entityWithLinearizationParentDifferentThanExistingParents_WHEN
"UNKNOWN",
"potatoParent",
"http://id.who.int/icd/release/11/ocu",
null));
null));

ValidationException exception = assertThrows(ValidationException.class, () -> service.updateEntity(dto, existingProjectId, eTag));
ValidationException exception = assertThrows(ValidationException.class, () -> service.updateEntity(dto, existingProjectId, eTag));

assertEquals("Entity has a linearization with parent potatoParent that is not in the available parents [http://id.who.int/icd/entity/1553463690]", exception.getMessage());
}
Expand All @@ -114,35 +116,35 @@ public void GIVEN_entityThatIsPresentAsOwnParent_WHEN_update_THEN_validationExce
);

dto.parents().add(dto.entityIRI());
ValidationException exception = assertThrows(ValidationException.class, () -> service.updateEntity(dto, existingProjectId, eTag));
ValidationException exception = assertThrows(ValidationException.class, () -> service.updateEntity(dto, existingProjectId, eTag));

assertEquals("Entity contains in the parents its own parents", exception.getMessage());
}

@Test
public void GIVEN_callWithDifferentHash_WHEN_update_THEN_versionDoesNotMatchExceptionIsThrown(){
public void GIVEN_callWithDifferentHash_WHEN_update_THEN_versionDoesNotMatchExceptionIsThrown() {
when(entityHistoryService.getEntityLatestChangeTime(eq(existingProjectId), eq(dto.entityIRI()))).thenReturn(
CompletableFuture.supplyAsync(() -> LocalDateTime.of(2024, 1, 1, 1, 1))
);

VersionDoesNotMatchException exception = assertThrows(VersionDoesNotMatchException.class, () -> service.updateEntity(dto, existingProjectId, "PotatoTag"));
VersionDoesNotMatchException exception = assertThrows(VersionDoesNotMatchException.class, () -> service.updateEntity(dto, existingProjectId, "PotatoTag"));

assertEquals("Received version out of date : Received hash PotatoTag is different from cd78e6f5802bff1df5f43103eb17e1b2cf17a3f4cf9b182e7d0194eb112ab3df", exception.getMessage());

}

@Test
public void GIVEN_getCall_WHEN_titleIsMissing_THEN_exceptionIsThrown(){
public void GIVEN_getCall_WHEN_titleIsMissing_THEN_exceptionIsThrown() {
initializeGetMocks();
when(entityLanguageTerms.title()).thenReturn(new LanguageTerm(null, null));
EntityIsMissingException exception = assertThrows(EntityIsMissingException.class, () -> service.getEntityInfo(dto.entityIRI(), existingProjectId));
EntityIsMissingException exception = assertThrows(EntityIsMissingException.class, () -> service.getEntityInfo(dto.entityIRI(), existingProjectId));

assertEquals("Entity with iri http://id.who.int/icd/entity/1855860109 is missing", exception.getMessage());

}

@Test
public void GIVEN_aValidUpdateRequest_WHEN_update_THEN_serviceIsCalled(){
public void GIVEN_aValidUpdateRequest_WHEN_update_THEN_serviceIsCalled() {
initializeGetMocks();

when(entityHistoryService.getEntityLatestChangeTime(eq(existingProjectId), eq(dto.entityIRI()))).thenReturn(
Expand All @@ -163,7 +165,7 @@ public void GIVEN_aValidUpdateRequest_WHEN_update_THEN_serviceIsCalled(){
}

@Test
public void GIVEN_validRequest_WHEN_callUpdate_THEN_entityUpdatedSuccessfullyIsEmitted(){
public void GIVEN_validRequest_WHEN_callUpdate_THEN_entityUpdatedSuccessfullyIsEmitted() {
initializeGetMocks();

when(entityHistoryService.getEntityLatestChangeTime(eq(existingProjectId), eq(dto.entityIRI()))).thenReturn(
Expand All @@ -179,7 +181,7 @@ public void GIVEN_validRequest_WHEN_callUpdate_THEN_entityUpdatedSuccessfullyIsE
}

@Test
public void GIVEN_applicationExceptionFromLinearization_WHEN_callUpdate_THEN_entityUpdateFailedEventIsEmitted(){
public void GIVEN_applicationExceptionFromLinearization_WHEN_callUpdate_THEN_entityUpdateFailedEventIsEmitted() {

when(entityHistoryService.getEntityLatestChangeTime(eq(existingProjectId), eq(dto.entityIRI()))).thenReturn(
CompletableFuture.supplyAsync(() -> LocalDateTime.of(2024, 1, 1, 1, 1))
Expand Down
Loading

0 comments on commit e84348a

Please sign in to comment.