diff --git a/core/identity-hub-credentials/src/main/java/org/eclipse/edc/identityhub/defaults/InMemoryEntityStore.java b/core/identity-hub-credentials/src/main/java/org/eclipse/edc/identityhub/defaults/InMemoryEntityStore.java index 3c030207c..e4d867be3 100644 --- a/core/identity-hub-credentials/src/main/java/org/eclipse/edc/identityhub/defaults/InMemoryEntityStore.java +++ b/core/identity-hub-credentials/src/main/java/org/eclipse/edc/identityhub/defaults/InMemoryEntityStore.java @@ -74,8 +74,7 @@ public StoreResult> query(QuerySpec querySpec) { lock.readLock().lock(); try { // if no filter is present, we return true - Predicate fallback = querySpec.getFilterExpression().isEmpty() ? x -> true : x -> false; - var result = queryResolver.query(store.values().stream(), querySpec, Predicate::or, fallback); + var result = queryResolver.query(store.values().stream(), querySpec, Predicate::and, x -> true); return success(result.toList()); } finally { lock.readLock().unlock(); diff --git a/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidDocumentServiceImpl.java b/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidDocumentServiceImpl.java index 113565420..e70ee690f 100644 --- a/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidDocumentServiceImpl.java +++ b/core/identity-hub-did/src/main/java/org/eclipse/edc/identityhub/did/DidDocumentServiceImpl.java @@ -27,12 +27,12 @@ import org.eclipse.edc.identityhub.spi.events.participant.ParticipantContextCreated; import org.eclipse.edc.identityhub.spi.events.participant.ParticipantContextDeleted; import org.eclipse.edc.identityhub.spi.events.participant.ParticipantContextUpdated; +import org.eclipse.edc.identityhub.spi.model.ParticipantResource; import org.eclipse.edc.security.token.jwt.CryptoConverter; import org.eclipse.edc.spi.event.Event; import org.eclipse.edc.spi.event.EventEnvelope; import org.eclipse.edc.spi.event.EventSubscriber; import org.eclipse.edc.spi.monitor.Monitor; -import org.eclipse.edc.spi.query.Criterion; import org.eclipse.edc.spi.query.QuerySpec; import org.eclipse.edc.spi.result.AbstractResult; import org.eclipse.edc.spi.result.ServiceResult; @@ -311,7 +311,7 @@ private void deleted(ParticipantContextDeleted event) { } private Collection findByParticipantId(String participantId) { - return didResourceStore.query(QuerySpec.Builder.newInstance().filter(new Criterion("participantId", "=", participantId)).build()); + return didResourceStore.query(ParticipantResource.queryByParticipantId(participantId).build()); } diff --git a/core/identity-hub-keypairs/src/main/java/org/eclipse/edc/identityhub/keypairs/KeyPairServiceImpl.java b/core/identity-hub-keypairs/src/main/java/org/eclipse/edc/identityhub/keypairs/KeyPairServiceImpl.java index f76ae733e..337b63509 100644 --- a/core/identity-hub-keypairs/src/main/java/org/eclipse/edc/identityhub/keypairs/KeyPairServiceImpl.java +++ b/core/identity-hub-keypairs/src/main/java/org/eclipse/edc/identityhub/keypairs/KeyPairServiceImpl.java @@ -21,6 +21,7 @@ import org.eclipse.edc.identityhub.spi.events.participant.ParticipantContextDeleted; import org.eclipse.edc.identityhub.spi.model.KeyPairResource; import org.eclipse.edc.identityhub.spi.model.KeyPairState; +import org.eclipse.edc.identityhub.spi.model.ParticipantResource; import org.eclipse.edc.identityhub.spi.model.participant.KeyDescriptor; import org.eclipse.edc.identityhub.spi.store.KeyPairResourceStore; import org.eclipse.edc.security.token.jwt.CryptoConverter; @@ -67,7 +68,7 @@ public ServiceResult addKeyPair(String participantId, KeyDescriptor keyDes // check if the new key is not active, and no other active key exists if (!keyDescriptor.isActive()) { - var hasActiveKeys = keyPairResourceStore.query(QuerySpec.Builder.newInstance().filter(new Criterion("participantId", "=", participantId)).build()) + var hasActiveKeys = keyPairResourceStore.query(ParticipantResource.queryByParticipantId(participantId).build()) .orElse(failure -> Collections.emptySet()) .stream().filter(kpr -> kpr.getState() == KeyPairState.ACTIVE.code()) .findAny() @@ -181,7 +182,7 @@ private void created(ParticipantContextCreated event) { private void deleted(ParticipantContextDeleted event) { //hard-delete all keypairs that are associated with the deleted participant - var query = QuerySpec.Builder.newInstance().filter(new Criterion("participantId", "=", event.getParticipantId())).build(); + var query = ParticipantResource.queryByParticipantId(event.getParticipantId()).build(); keyPairResourceStore.query(query) .compose(list -> { var x = list.stream().map(r -> keyPairResourceStore.deleteById(r.getId())) diff --git a/core/identity-hub-participants/src/main/java/org/eclipse/edc/identityhub/participantcontext/ParticipantContextServiceImpl.java b/core/identity-hub-participants/src/main/java/org/eclipse/edc/identityhub/participantcontext/ParticipantContextServiceImpl.java index a994fd663..3098c32aa 100644 --- a/core/identity-hub-participants/src/main/java/org/eclipse/edc/identityhub/participantcontext/ParticipantContextServiceImpl.java +++ b/core/identity-hub-participants/src/main/java/org/eclipse/edc/identityhub/participantcontext/ParticipantContextServiceImpl.java @@ -16,11 +16,11 @@ import org.eclipse.edc.identityhub.spi.ParticipantContextService; import org.eclipse.edc.identityhub.spi.events.participant.ParticipantContextObservable; +import org.eclipse.edc.identityhub.spi.model.ParticipantResource; import org.eclipse.edc.identityhub.spi.model.participant.ParticipantContext; import org.eclipse.edc.identityhub.spi.model.participant.ParticipantContextState; import org.eclipse.edc.identityhub.spi.model.participant.ParticipantManifest; import org.eclipse.edc.identityhub.spi.store.ParticipantContextStore; -import org.eclipse.edc.spi.query.Criterion; import org.eclipse.edc.spi.query.QuerySpec; import org.eclipse.edc.spi.result.ServiceResult; import org.eclipse.edc.spi.security.Vault; @@ -73,7 +73,7 @@ public ServiceResult createParticipantContext(ParticipantManifest manife @Override public ServiceResult getParticipantContext(String participantId) { return transactionContext.execute(() -> { - var res = participantContextStore.query(QuerySpec.Builder.newInstance().filter(new Criterion("participantId", "=", participantId)).build()); + var res = participantContextStore.query(ParticipantResource.queryByParticipantId(participantId).build()); if (res.succeeded()) { return res.getContent().stream().findFirst() .map(ServiceResult::success) @@ -149,7 +149,7 @@ private ServiceResult createParticipantContext(ParticipantContext context) } private ParticipantContext findByIdInternal(String participantId) { - var resultStream = participantContextStore.query(QuerySpec.Builder.newInstance().filter(new Criterion("participantId", "=", participantId)).build()); + var resultStream = participantContextStore.query(ParticipantResource.queryByParticipantId(participantId).build()); if (resultStream.failed()) return null; return resultStream.getContent().stream().findFirst().orElse(null); } diff --git a/e2e-tests/api-tests/src/test/java/org/eclipse/edc/identityhub/tests/ManagementApiEndToEndTest.java b/e2e-tests/api-tests/src/test/java/org/eclipse/edc/identityhub/tests/ManagementApiEndToEndTest.java index f5dd1e4a7..c861cb128 100644 --- a/e2e-tests/api-tests/src/test/java/org/eclipse/edc/identityhub/tests/ManagementApiEndToEndTest.java +++ b/e2e-tests/api-tests/src/test/java/org/eclipse/edc/identityhub/tests/ManagementApiEndToEndTest.java @@ -21,6 +21,7 @@ import org.eclipse.edc.identityhub.spi.ParticipantContextService; import org.eclipse.edc.identityhub.spi.authentication.ServicePrincipal; import org.eclipse.edc.identityhub.spi.model.KeyPairResource; +import org.eclipse.edc.identityhub.spi.model.ParticipantResource; import org.eclipse.edc.identityhub.spi.model.participant.KeyDescriptor; import org.eclipse.edc.identityhub.spi.model.participant.ParticipantContext; import org.eclipse.edc.identityhub.spi.model.participant.ParticipantManifest; @@ -96,9 +97,8 @@ protected T getService(Class type) { } protected Collection getKeyPairsForParticipant(String participantId) { - return getService(KeyPairResourceStore.class).query(QuerySpec.Builder.newInstance() - .filter(new Criterion("participantId", "=", participantId)) - .build()).getContent(); + return getService(KeyPairResourceStore.class).query(ParticipantResource.queryByParticipantId(participantId).build()) + .getContent(); } protected Collection getDidForParticipant(String participantId) { diff --git a/extensions/api/keypair-mgmt-api/src/main/java/org/eclipse/edc/identityhub/api/keypair/v1/KeyPairResourceApiController.java b/extensions/api/keypair-mgmt-api/src/main/java/org/eclipse/edc/identityhub/api/keypair/v1/KeyPairResourceApiController.java index 7c0f595c3..0050ea71c 100644 --- a/extensions/api/keypair-mgmt-api/src/main/java/org/eclipse/edc/identityhub/api/keypair/v1/KeyPairResourceApiController.java +++ b/extensions/api/keypair-mgmt-api/src/main/java/org/eclipse/edc/identityhub/api/keypair/v1/KeyPairResourceApiController.java @@ -28,6 +28,7 @@ import org.eclipse.edc.identityhub.spi.AuthorizationService; import org.eclipse.edc.identityhub.spi.KeyPairService; import org.eclipse.edc.identityhub.spi.model.KeyPairResource; +import org.eclipse.edc.identityhub.spi.model.ParticipantResource; import org.eclipse.edc.identityhub.spi.model.participant.KeyDescriptor; import org.eclipse.edc.identityhub.spi.model.participant.ParticipantContext; import org.eclipse.edc.spi.EdcException; @@ -80,7 +81,7 @@ public KeyPairResource findById(@PathParam("keyPairId") String id, @Context Secu @Override public Collection findForParticipant(@PathParam("participantId") String participantId, @Context SecurityContext securityContext) { return onEncoded(participantId).map(decoded -> { - var query = QuerySpec.Builder.newInstance().filter(new Criterion("participantId", "=", decoded)).build(); + var query = ParticipantResource.queryByParticipantId(decoded).build(); return keyPairService.query(query).orElseThrow(exceptionMapper(KeyPairResource.class, decoded)).stream().filter(kpr -> authorizationService.isAuthorized(securityContext, kpr.getId(), KeyPairResource.class).succeeded()).toList(); }).orElseThrow(InvalidRequestException::new); } diff --git a/spi/identity-hub-did-spi/src/testFixtures/java/org/eclipse/edc/identityhub/did/store/test/DidResourceStoreTestBase.java b/spi/identity-hub-did-spi/src/testFixtures/java/org/eclipse/edc/identityhub/did/store/test/DidResourceStoreTestBase.java index 4d590471a..3bd89fbf3 100644 --- a/spi/identity-hub-did-spi/src/testFixtures/java/org/eclipse/edc/identityhub/did/store/test/DidResourceStoreTestBase.java +++ b/spi/identity-hub-did-spi/src/testFixtures/java/org/eclipse/edc/identityhub/did/store/test/DidResourceStoreTestBase.java @@ -21,6 +21,7 @@ import org.eclipse.edc.identithub.did.spi.model.DidResource; import org.eclipse.edc.identithub.did.spi.model.DidState; import org.eclipse.edc.identithub.did.spi.store.DidResourceStore; +import org.eclipse.edc.identityhub.spi.model.ParticipantResource; import org.eclipse.edc.spi.message.Range; import org.eclipse.edc.spi.query.Criterion; import org.eclipse.edc.spi.query.QuerySpec; @@ -158,7 +159,7 @@ void query_byParticipantId() { dids.add(expected); dids.forEach(getStore()::save); - var q = QuerySpec.Builder.newInstance().filter(new Criterion("participantId", "=", expected.getParticipantId())).build(); + var q = ParticipantResource.queryByParticipantId(expected.getParticipantId()).build(); Assertions.assertThat(getStore().query(q)) .hasSize(1) .usingRecursiveFieldByFieldElementComparator() diff --git a/spi/identity-hub-store-spi/src/testFixtures/java/org/eclipse/edc/identityhub/store/test/CredentialStoreTestBase.java b/spi/identity-hub-store-spi/src/testFixtures/java/org/eclipse/edc/identityhub/store/test/CredentialStoreTestBase.java index 296fd1deb..11fd7c81e 100644 --- a/spi/identity-hub-store-spi/src/testFixtures/java/org/eclipse/edc/identityhub/store/test/CredentialStoreTestBase.java +++ b/spi/identity-hub-store-spi/src/testFixtures/java/org/eclipse/edc/identityhub/store/test/CredentialStoreTestBase.java @@ -15,6 +15,7 @@ package org.eclipse.edc.identityhub.store.test; import org.assertj.core.api.Assertions; +import org.eclipse.edc.identityhub.spi.model.ParticipantResource; import org.eclipse.edc.identityhub.spi.model.VcState; import org.eclipse.edc.identityhub.spi.model.VerifiableCredentialResource; import org.eclipse.edc.identityhub.spi.store.CredentialStore; @@ -133,8 +134,7 @@ void query_byParticipantId() { .build()) .forEach(getStore()::create); - var query = QuerySpec.Builder.newInstance() - .filter(new Criterion("participantId", "=", "participant2")) + var query = ParticipantResource.queryByParticipantId("participant2") .build(); assertThat(getStore().query(query)).isSucceeded() @@ -153,8 +153,7 @@ void query_byParticipantIdAndType() { Arrays.asList(cred1, cred2, cred3).forEach(getStore()::create); - var query = QuerySpec.Builder.newInstance() - .filter(new Criterion("participantId", "=", TEST_PARTICIPANT_CONTEXT_ID)) + var query = ParticipantResource.queryByParticipantId(TEST_PARTICIPANT_CONTEXT_ID) .filter(new Criterion("verifiableCredential.credential.type", "contains", "UniversityDegreeCredential")) .build(); diff --git a/spi/identity-hub-store-spi/src/testFixtures/java/org/eclipse/edc/identityhub/store/test/KeyPairResourceStoreTestBase.java b/spi/identity-hub-store-spi/src/testFixtures/java/org/eclipse/edc/identityhub/store/test/KeyPairResourceStoreTestBase.java index b90b299b5..7fa0a43c3 100644 --- a/spi/identity-hub-store-spi/src/testFixtures/java/org/eclipse/edc/identityhub/store/test/KeyPairResourceStoreTestBase.java +++ b/spi/identity-hub-store-spi/src/testFixtures/java/org/eclipse/edc/identityhub/store/test/KeyPairResourceStoreTestBase.java @@ -17,12 +17,14 @@ import org.assertj.core.api.Assertions; import org.eclipse.edc.identityhub.spi.model.KeyPairResource; import org.eclipse.edc.identityhub.spi.model.KeyPairState; +import org.eclipse.edc.identityhub.spi.model.ParticipantResource; import org.eclipse.edc.identityhub.spi.store.KeyPairResourceStore; import org.eclipse.edc.spi.query.Criterion; import org.eclipse.edc.spi.query.QuerySpec; import org.junit.jupiter.api.Test; import java.time.Duration; +import java.util.List; import java.util.UUID; import static java.util.stream.IntStream.range; @@ -100,8 +102,7 @@ void query_whenNotFound() { resources.forEach(getStore()::create); - var query = QuerySpec.Builder.newInstance() - .filter(new Criterion("participantId", "=", "id7")) + var query = ParticipantResource.queryByParticipantId("id7") .build(); var res = getStore().query(query); assertThat(res).isSucceeded(); @@ -126,6 +127,27 @@ void query_byInvalidField_shouldReturnEmptyList() { Assertions.assertThat(res.getContent()).isNotNull().isEmpty(); } + @Test + void query_byIdAndState() { + var kp1 = createKeyPairResource().id("id1").state(KeyPairState.ACTIVE).build(); + var kp2 = createKeyPairResource().id("id2").state(KeyPairState.CREATED).build(); + var kp3 = createKeyPairResource().id("id3").state(KeyPairState.REVOKED).build(); + var kp4 = createKeyPairResource().id("id4").state(KeyPairState.ROTATED).build(); + + List.of(kp1, kp2, kp3, kp4).forEach(getStore()::create); + + var query = QuerySpec.Builder.newInstance() + .filter(new Criterion("id", "=", "id3")) + .filter(new Criterion("state", "=", KeyPairState.REVOKED.code())) + .build(); + + assertThat(getStore().query(query)) + .isSucceeded() + .satisfies(keyPairResources -> Assertions.assertThat(keyPairResources) + .usingRecursiveFieldByFieldElementComparator() + .containsExactly(kp3)); + } + @Test void update() { var keyPairResource = createKeyPairResource(); diff --git a/spi/identity-hub-store-spi/src/testFixtures/java/org/eclipse/edc/identityhub/store/test/ParticipantContextStoreTestBase.java b/spi/identity-hub-store-spi/src/testFixtures/java/org/eclipse/edc/identityhub/store/test/ParticipantContextStoreTestBase.java index 1b5ba3f44..25bdae2b0 100644 --- a/spi/identity-hub-store-spi/src/testFixtures/java/org/eclipse/edc/identityhub/store/test/ParticipantContextStoreTestBase.java +++ b/spi/identity-hub-store-spi/src/testFixtures/java/org/eclipse/edc/identityhub/store/test/ParticipantContextStoreTestBase.java @@ -15,6 +15,7 @@ package org.eclipse.edc.identityhub.store.test; import org.assertj.core.api.Assertions; +import org.eclipse.edc.identityhub.spi.model.ParticipantResource; import org.eclipse.edc.identityhub.spi.model.participant.ParticipantContext; import org.eclipse.edc.identityhub.spi.store.ParticipantContextStore; import org.eclipse.edc.spi.query.Criterion; @@ -57,8 +58,7 @@ void query_byId() { .mapToObj(i -> createParticipantContextBuilder().participantId("id" + i).build()) .forEach(getStore()::create); - var query = QuerySpec.Builder.newInstance() - .filter(new Criterion("participantId", "=", "id2")) + var query = ParticipantResource.queryByParticipantId("id2") .build(); assertThat(getStore().query(query)).isSucceeded() @@ -106,8 +106,7 @@ void query_whenNotFound() { resources.forEach(getStore()::create); - var query = QuerySpec.Builder.newInstance() - .filter(new Criterion("participantId", "=", "id7")) + var query = ParticipantResource.queryByParticipantId("id7") .build(); var res = getStore().query(query); assertThat(res).isSucceeded();