diff --git a/src/main/java/com/metaformsystems/redline/domain/service/DataAccessService.java b/src/main/java/com/metaformsystems/redline/domain/service/DataAccessService.java index f117c71..e414b01 100644 --- a/src/main/java/com/metaformsystems/redline/domain/service/DataAccessService.java +++ b/src/main/java/com/metaformsystems/redline/domain/service/DataAccessService.java @@ -24,6 +24,7 @@ import com.metaformsystems.redline.infrastructure.client.management.ManagementApiClient; import com.metaformsystems.redline.infrastructure.client.management.dto.Asset; import com.metaformsystems.redline.infrastructure.client.management.dto.Catalog; +import com.metaformsystems.redline.infrastructure.client.management.dto.CatalogRequest; import com.metaformsystems.redline.infrastructure.client.management.dto.CelExpression; import com.metaformsystems.redline.infrastructure.client.management.dto.ContractNegotiation; import com.metaformsystems.redline.infrastructure.client.management.dto.ContractRequest; @@ -253,7 +254,13 @@ public byte[] downloadData(Long participantId, String fileId, String authToken) } private CacheableEntry fetchCatalog(String participantId, String did) { - return new CacheableEntry<>(managementApiClient.getCatalog(participantId, did), Instant.now()); + var counterPartyAddress = webDidResolver.resolveProtocolEndpoints(did); + var request = CatalogRequest.Builder.newInstance() + .counterPartyId(did) + .counterPartyAddress(counterPartyAddress) + .build(); + + return new CacheableEntry<>(managementApiClient.getCatalog(participantId, request), Instant.now()); } /** diff --git a/src/main/java/com/metaformsystems/redline/infrastructure/client/management/ManagementApiClient.java b/src/main/java/com/metaformsystems/redline/infrastructure/client/management/ManagementApiClient.java index 5e3c9c6..c4b674c 100644 --- a/src/main/java/com/metaformsystems/redline/infrastructure/client/management/ManagementApiClient.java +++ b/src/main/java/com/metaformsystems/redline/infrastructure/client/management/ManagementApiClient.java @@ -16,6 +16,7 @@ import com.metaformsystems.redline.infrastructure.client.management.dto.Asset; import com.metaformsystems.redline.infrastructure.client.management.dto.Catalog; +import com.metaformsystems.redline.infrastructure.client.management.dto.CatalogRequest; import com.metaformsystems.redline.infrastructure.client.management.dto.CelExpression; import com.metaformsystems.redline.infrastructure.client.management.dto.ContractAgreement; import com.metaformsystems.redline.infrastructure.client.management.dto.ContractNegotiation; @@ -77,14 +78,11 @@ public interface ManagementApiClient { TransferProcess getTransferProcess(String participantContextId, String transferProcessId); // Catalog - Catalog getCatalog(String participantContextId, String counterPartyId); + Catalog getCatalog(String participantContextId, CatalogRequest request); // others void prepareDataplane(String participantContextId, DataplaneRegistration dataplaneRegistration); - Object getData(String participantContextId, String counterPartyId, String offerId); - - List listContracts(String participantContextId); ContractAgreement getAgreement(String participantContextId, String negotiationId); diff --git a/src/main/java/com/metaformsystems/redline/infrastructure/client/management/ManagementApiClientImpl.java b/src/main/java/com/metaformsystems/redline/infrastructure/client/management/ManagementApiClientImpl.java index 5624e65..793147f 100644 --- a/src/main/java/com/metaformsystems/redline/infrastructure/client/management/ManagementApiClientImpl.java +++ b/src/main/java/com/metaformsystems/redline/infrastructure/client/management/ManagementApiClientImpl.java @@ -22,6 +22,7 @@ import com.metaformsystems.redline.domain.repository.ParticipantRepository; import com.metaformsystems.redline.infrastructure.client.management.dto.Asset; import com.metaformsystems.redline.infrastructure.client.management.dto.Catalog; +import com.metaformsystems.redline.infrastructure.client.management.dto.CatalogRequest; import com.metaformsystems.redline.infrastructure.client.management.dto.CelExpression; import com.metaformsystems.redline.infrastructure.client.management.dto.ContractAgreement; import com.metaformsystems.redline.infrastructure.client.management.dto.ContractNegotiation; @@ -274,11 +275,11 @@ public TransferProcess getTransferProcess(String participantContextId, String tr } @Override - public Catalog getCatalog(String participantContextId, String counterPartyDid) { + public Catalog getCatalog(String participantContextId, CatalogRequest request) { return controlPlaneWebClient.post() - .uri("/v1alpha/participants/%s/catalog".formatted(participantContextId)) + .uri("/v5beta/participants/%s/catalog/request".formatted(participantContextId)) .header("Authorization", "Bearer " + getToken(participantContextId)) - .bodyValue(Map.of("counterPartyDid", counterPartyDid)) + .bodyValue(request) .retrieve() .bodyToMono(Catalog.class) .block(); @@ -296,20 +297,6 @@ public void prepareDataplane(String participantContextId, DataplaneRegistration .block(); } - @Override - public Object getData(String participantContextId, String counterPartyId, String policyId) { - return controlPlaneWebClient.post() - .uri("/v1alpha/participants/%s/data".formatted(participantContextId)) - .header("Authorization", "Bearer " + getToken(participantContextId)) - .bodyValue(Map.of( - "providerId", counterPartyId, - "policyId", policyId)) - .retrieve() - .bodyToMono(new ParameterizedTypeReference<>() { - }) - .block(); - } - @Override public List listContracts(String participantContextId) { return controlPlaneWebClient.post() diff --git a/src/main/java/com/metaformsystems/redline/infrastructure/client/management/dto/CatalogRequest.java b/src/main/java/com/metaformsystems/redline/infrastructure/client/management/dto/CatalogRequest.java new file mode 100644 index 0000000..eb108c9 --- /dev/null +++ b/src/main/java/com/metaformsystems/redline/infrastructure/client/management/dto/CatalogRequest.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2026 Metaform Systems, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + * + * Contributors: + * Metaform Systems, Inc. - initial API and implementation + * + */ + +package com.metaformsystems.redline.infrastructure.client.management.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Map; + +public class CatalogRequest { + @JsonProperty("@context") + private final String[] context = new String[]{ + "https://w3id.org/edc/connector/management/v2", + }; + @JsonProperty("@type") + private final String type = "CatalogRequest"; + private String protocol = "dataspace-protocol-http:2025-1"; + private String counterPartyAddress; + private String counterPartyId; + + public String[] getContext() { + return context; + } + + public String getType() { + return type; + } + + public String getCounterPartyAddress() { + return counterPartyAddress; + } + + public String getProtocol() { + return protocol; + } + + public String getCounterPartyId() { + return counterPartyId; + } + + public static final class Builder { + private final CatalogRequest transferRequest; + + private Builder() { + transferRequest = new CatalogRequest(); + } + + public static Builder newInstance() { + return new Builder(); + } + + public Builder counterPartyAddress(String counterPartyAddress) { + transferRequest.counterPartyAddress = counterPartyAddress; + return this; + } + + public Builder protocol(String protocol) { + transferRequest.protocol = protocol; + return this; + } + + public Builder counterPartyId(String counterPartyId) { + transferRequest.counterPartyId = counterPartyId; + return this; + } + + public CatalogRequest build() { + return transferRequest; + } + } +} diff --git a/src/test/java/com/metaformsystems/redline/OnboardingEndToEndTest.java b/src/test/java/com/metaformsystems/redline/OnboardingEndToEndTest.java deleted file mode 100644 index 15d4473..0000000 --- a/src/test/java/com/metaformsystems/redline/OnboardingEndToEndTest.java +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Copyright (c) 2026 Metaform Systems, Inc. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - * - * Contributors: - * Metaform Systems, Inc. - initial API and implementation - * - */ - -package com.metaformsystems.redline; - -import com.metaformsystems.redline.api.dto.request.DataspaceInfo; -import com.metaformsystems.redline.api.dto.request.ParticipantDeployment; -import com.metaformsystems.redline.api.dto.request.TenantRegistration; -import com.metaformsystems.redline.api.dto.request.TransferProcessRequest; -import com.metaformsystems.redline.domain.entity.Dataspace; -import com.metaformsystems.redline.domain.entity.ServiceProvider; -import com.metaformsystems.redline.domain.repository.DataspaceRepository; -import com.metaformsystems.redline.domain.repository.ServiceProviderRepository; -import com.metaformsystems.redline.domain.service.DataAccessService; -import com.metaformsystems.redline.domain.service.TenantService; -import com.metaformsystems.redline.infrastructure.client.dataplane.DataPlaneApiClient; -import com.metaformsystems.redline.infrastructure.client.identityhub.IdentityHubClient; -import com.metaformsystems.redline.infrastructure.client.management.ManagementApiClient; -import com.metaformsystems.redline.infrastructure.client.management.dto.Asset; -import com.metaformsystems.redline.infrastructure.client.management.dto.CelExpression; -import com.metaformsystems.redline.infrastructure.client.management.dto.ContractNegotiation; -import com.metaformsystems.redline.infrastructure.client.management.dto.ContractRequest; -import com.metaformsystems.redline.infrastructure.client.management.dto.Criterion; -import com.metaformsystems.redline.infrastructure.client.management.dto.DataplaneRegistration; -import com.metaformsystems.redline.infrastructure.client.management.dto.NewContractDefinition; -import com.metaformsystems.redline.infrastructure.client.management.dto.NewPolicyDefinition; -import com.metaformsystems.redline.infrastructure.client.management.dto.Offer; -import com.metaformsystems.redline.infrastructure.client.management.dto.PolicySet; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; - -import java.io.IOException; -import java.time.Duration; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicReference; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.awaitility.Awaitility.await; - -@EnabledIfEnvironmentVariable(named = "ENABLE_ONBOARDING_TESTS", matches = "true", disabledReason = "This can only run if ENABLE_ONBOARDING_TESTS=true is set in the environment.") -@SpringBootTest -@ActiveProfiles("dev") -// disable transactional tests, because awaitility is used, and opening new threads creates new transactions. -@Transactional(propagation = Propagation.NOT_SUPPORTED) -public class OnboardingEndToEndTest { - @Autowired - private TenantService tenantService; - @Autowired - private DataAccessService dataAccessService; - @Autowired - private ManagementApiClient managementApiClient; - @Autowired - private DataspaceRepository dataspaceRepository; - @Autowired - private ServiceProviderRepository serviceProviderRepository; - @Autowired - private IdentityHubClient identityHubClient; - @Autowired - private DataPlaneApiClient dataPlaneApiClient; - - private ServiceProvider serviceProvider; - private Dataspace dataspace; - - - @DynamicPropertySource - static void configureProperties(DynamicPropertyRegistry registry) { - registry.add("tenant-manager.url", () -> "http://tm.vps.beardyinc.com"); - registry.add("vault.url", () -> "http://vault.vps.beardyinc.com"); - registry.add("identityhub.url", () -> "http://ih.vps.beardyinc.com/cs"); - registry.add("controlplane.url", () -> "http://cp.vps.beardyinc.com/api/mgmt"); - registry.add("dataplane.internal.url", () -> "http://dp.vps.beardyinc.com/app/internal/api/control"); - registry.add("dataplane.url", () -> "http://dp.vps.beardyinc.com/app/public/api/data"); - registry.add("keycloak.tokenurl", () -> "http://auth.vps.beardyinc.com/realms/edcv/protocol/openid-connect/token"); - } - - @BeforeEach - void setUp() { - // Create test data - serviceProvider = new ServiceProvider(); - serviceProvider.setName("Test Provider"); - serviceProvider = serviceProviderRepository.save(serviceProvider); - - dataspace = new Dataspace(); - dataspace.setName("Test Dataspace"); - dataspace = dataspaceRepository.save(dataspace); - } - - @Test - void shouldOnboard() { - - var participantInfo = onboardParticipant(); - - // now for some test assertions: - assertThat(identityHubClient.getParticipant(participantInfo.contextId())).isNotNull(); - assertThat(identityHubClient.queryCredentialsByType(participantInfo.contextId(), "MembershipCredential")).hasSize(1); - } - - @Test - void shouldDownloadTodo() { - var providerInfo = onboardParticipant(); - var consumerInfo = onboardParticipant(); - - // prepare consumer: create CEL expression - managementApiClient.createCelExpression(CelExpression.Builder.aNewCelExpression() - .id("membership_expr_" + consumerInfo.contextId()) - .leftOperand("MembershipCredential") - .description("Expression for evaluating membership credential") - .scopes(Set.of("catalog", "contract.negotiation", "transfer.process")) - .expression("ctx.agent.claims.vc.filter(c, c.type.exists(t, t == 'MembershipCredential')).exists(c, c.credentialSubject.exists(cs, timestamp(cs.membershipStartDate) < now))") - .build()); - - //prepare provider - create asset, policy etc. - var todoAssetId = "todo_asset_" + providerInfo.contextId(); - publishHttpAsset(providerInfo.contextId(), todoAssetId); - registerDataPlane(providerInfo.contextId()); - - // now acting as the consumer, getting the provider's catalog - var catalog = dataAccessService.requestCatalog(consumerInfo.id(), providerInfo.webDid(), "no-cache"); - - // get the asset with id "todo_asset" - var dataset = catalog.getDataset().stream().filter(ds -> ds.getId().equals(todoAssetId)).findFirst().orElseThrow(); - var offers = dataset.getHasPolicy(); - - var policyId = offers.getFirst().getId(); - assertThat(policyId).isNotNull(); - - // start transfer using the all-in-one API from JAD - var result = managementApiClient.getData(consumerInfo.contextId(), providerInfo.webDid(), policyId); - assertThat(result).isNotNull().isInstanceOf(List.class); - - // check transfer process - var transferProcesses = dataAccessService.listTransferProcesses(consumerInfo.id()); - assertThat(transferProcesses).isNotEmpty(); - assertThat(transferProcesses.getFirst().getContractId()).isNotNull(); - - //check contracts - var contracts = dataAccessService.listContracts(consumerInfo.id()); - assertThat(contracts).isNotEmpty(); - assertThat(contracts).allSatisfy(c -> assertThat(c.getContractAgreement()).isNotNull()); - } - - @Test - void shouldInitiateContractNegotiation() { - var providerInfo = onboardParticipant(); - var consumerInfo = onboardParticipant(); - - // prepare consumer: create CEL expression - managementApiClient.createCelExpression(CelExpression.Builder.aNewCelExpression() - .id("membership_expr_" + consumerInfo.contextId()) - .leftOperand("MembershipCredential") - .description("Expression for evaluating membership credential") - .scopes(Set.of("catalog", "contract.negotiation", "transfer.process")) - .expression("ctx.agent.claims.vc.filter(c, c.type.exists(t, t == 'MembershipCredential')).exists(c, c.credentialSubject.exists(cs, timestamp(cs.membershipStartDate) < now))") - .build()); - - //prepare provider - create asset, policy etc. - var todoAssetId = "todo_asset_" + providerInfo.contextId(); - publishHttpAsset(providerInfo.contextId(), todoAssetId); - registerDataPlane(providerInfo.contextId()); - - // now acting as the consumer, getting the provider's catalog - var catalog = dataAccessService.requestCatalog(consumerInfo.id(), providerInfo.webDid(), "no-cache"); - - // get the asset with negotiationId "todo_asset" - var dataset = catalog.getDataset().stream().filter(ds -> ds.getId().equals(todoAssetId)).findFirst().orElseThrow(); - var offers = dataset.getHasPolicy(); - - var first = offers.getFirst(); - var policyId = first.getId(); - var dspEndpointUrl = catalog.getService().getFirst().getEndpointUrl(); - assertThat(policyId).isNotNull(); - assertThat(dspEndpointUrl).isNotNull(); - - // start transfer using the all-in-one API from JAD - var cr = ContractRequest.Builder.aContractRequest() - .providerId(providerInfo.webDid()) - .counterPartyAddress(dspEndpointUrl) - .callbackAddresses(Set.of()) - .policy(Offer.Builder.anOffer() - .id(policyId) - .assigner(providerInfo.webDid()) - .obligation(first.getObligation()) - .permission(first.getPermission()) - .prohibition(first.getProhibition()) - .target(todoAssetId) - .build()) - .build(); - var negotiationId = dataAccessService.initiateContractNegotiation(consumerInfo.id(), cr); - assertThat(negotiationId).isNotNull(); - - // wait for negotiation to finalize - AtomicReference cn = new AtomicReference<>(dataAccessService.getContractNegotiation(consumerInfo.id(), negotiationId)); - assertThat(cn).isNotNull(); - assertThat(cn.get().getContractAgreementId()).isNull(); - - await().atMost(Duration.ofSeconds(30)) - .pollInterval(Duration.ofSeconds(1)) - .untilAsserted(() -> { - var updatedCn = dataAccessService.getContractNegotiation(consumerInfo.id(), negotiationId); - assertThat(updatedCn.getContractAgreementId()).isNotNull(); - assertThat(updatedCn.getState()).isEqualTo("FINALIZED"); - cn.set(updatedCn); - }); - - - // initiate transfer - var rq = TransferProcessRequest.Builder.aNewTransferRequest() - .counterPartyId(dspEndpointUrl) - .contractId(cn.get().getContractAgreementId()) - .dataDestination(Map.of( - "@type", "DataAddress", - "type", "HttpData")) - .transferType("HttpData-PULL") - .build(); - var transferId = dataAccessService.initiateTransferProcess(consumerInfo.id(), rq); - assertThat(transferId).isNotNull(); - - await().atMost(Duration.ofSeconds(30)) - .pollInterval(Duration.ofSeconds(1)) - .untilAsserted(() -> { - var tps = dataAccessService.getTransferProcess(consumerInfo.id(), transferId); - assertThat(tps).isNotNull(); - assertThat(tps.getState()).isEqualTo("STARTED"); - }); - } - - @Test - void shouldDownloadCert() throws IOException { - var providerInfo = onboardParticipant(); - var consumerInfo = onboardParticipant(); - - // prepare consumer: create CEL expression - managementApiClient.createCelExpression(CelExpression.Builder.aNewCelExpression() - .id("membership_expr_" + consumerInfo.contextId()) - .leftOperand("MembershipCredential") - .description("Expression for evaluating membership credential") - .scopes(Set.of("catalog", "contract.negotiation", "transfer.process")) - .expression("ctx.agent.claims.vc.filter(c, c.type.exists(t, t == 'MembershipCredential')).exists(c, c.credentialSubject.exists(cs, timestamp(cs.membershipStartDate) < now))") - .build()); - - //prepare provider - create asset, policy etc. - var certAssertId = "cert_asset_" + providerInfo.contextId(); - var fileId = publishCertificateAsset(providerInfo.contextId(), certAssertId, "testdocument.pdf"); - registerDataPlane(providerInfo.contextId()); - - // now acting as the consumer, getting the provider's catalog - var catalog = managementApiClient.getCatalog(consumerInfo.contextId(), providerInfo.webDid()); - - // get the asset with id "cert_asset" - var dataset = catalog.getDataset().stream().filter(ds -> ds.getId().equals(certAssertId)).findFirst().orElseThrow(); - var offers = dataset.getHasPolicy(); - - var policyId = offers.getFirst().getId(); - assertThat(policyId).isNotNull(); - - var endpointDataReference = managementApiClient.setupTransfer(consumerInfo.contextId(), policyId, providerInfo.webDid()); - var bytes = dataPlaneApiClient.downloadFile(endpointDataReference.get("https://w3id.org/edc/v0.0.1/ns/authorization"), fileId); - var expectedBytes = Thread.currentThread().getContextClassLoader().getResourceAsStream("testdocument.pdf").readAllBytes(); - assertThat(bytes).isEqualTo(expectedBytes); - } - - private String publishCertificateAsset(String participantContextId, String certificateAssetId, String resourceName) { - // create HTTP asset - var permission = "membership_asset"; - managementApiClient.createAsset(participantContextId, Asset.Builder.aNewAsset() - .id(certificateAssetId) - .properties(Map.of("description", "This asset requires the Membership credential to access")) - .privateProperties(Map.of("permission", permission)) - .dataAddress(Map.of( - "@type", "DataAddress", - "type", "HttpCertData")) - .build()); - // create policy - var membershipPolicy = "membership_policy_" + participantContextId; - managementApiClient.createPolicy(participantContextId, NewPolicyDefinition.Builder.aNewPolicyDefinition() - .id(membershipPolicy) - .policy(new PolicySet(List.of(new PolicySet.Permission("use", List.of(new PolicySet.Constraint("MembershipCredential", "eq", "active")))))) - .build()); - - // create contract definition - var membershipContractDef = "membership_contract_def_" + participantContextId; - managementApiClient.createContractDefinition(participantContextId, NewContractDefinition.Builder.aNewContractDefinition() - .id(membershipContractDef) - .accessPolicyId(membershipPolicy) - .contractPolicyId(membershipPolicy) - .assetsSelector(Set.of(new Criterion("privateProperties.'https://w3id.org/edc/v0.0.1/ns/permission'", - "=", permission))) - .build()); - - var fileId = new AtomicReference(); - try (var is = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName)) { - var response = dataPlaneApiClient.uploadMultipart(participantContextId, Map.of(), is); - fileId.set(response.id()); - } catch (IOException e) { - throw new AssertionError(e); - } - return fileId.get(); - } - - @NotNull - private ParticipantInfo onboardParticipant() { - var slug = UUID.randomUUID().toString(); - var infos = List.of(new DataspaceInfo(dataspace.getId(), List.of(), List.of(), Map.of())); - var tenantName = "Test Tenant " + slug; - var registration = new TenantRegistration(tenantName, infos); - var tenant = tenantService.registerTenant(serviceProvider.getId(), registration); - var participant = tenant.participants().getFirst(); - - var webDid = "did:web:identityhub.edc-v.svc.cluster.local%3A7083:test-participant-" + slug; - var deployment = new ParticipantDeployment(participant.id(), webDid); - - // deploy the profile to CFM - var result = tenantService.deployParticipant(deployment); - - // wait for it to complete - var participantContextId = new AtomicReference(); - await() - .pollDelay(Duration.ofSeconds(1)) - .pollInterval(Duration.ofSeconds(1)) - .atMost(Duration.ofSeconds(60)) - .untilAsserted(() -> { - var pcId = tenantService.getParticipantContextId(result.id()); - assertThat(pcId).isNotNull(); - participantContextId.set(pcId); - }); - - // fetch the secret from the vault - var clientCredentials = tenantService.getClientCredentials(participantContextId.get()); - assertThat(clientCredentials).isNotNull(); - - return new ParticipantInfo(participantContextId.get(), webDid, participant.id()); - } - - private void registerDataPlane(String participantContextId) { - managementApiClient.prepareDataplane(participantContextId, DataplaneRegistration.Builder.aDataplaneRegistration() - .allowedTransferTypes(List.of("HttpData-PULL")) - .url("http://siglet.edc-v.svc.cluster.local:8081/api/v1/dataflows") //todo: replace with config - .build()); - } - - private void publishHttpAsset(String participantContextId, String assetId) { - // create HTTP asset - var permission = "membership_asset"; - managementApiClient.createAsset(participantContextId, Asset.Builder.aNewAsset() - .id(assetId) - .properties(Map.of("description", "This asset requires the Membership credential to access")) - .privateProperties(Map.of("permission", permission)) - .dataAddress(Map.of( - "@type", "DataAddress", - "type", "HttpData", - "baseUrl", "https://jsonplaceholder.typicode.com/todos", - "proxyPath", "true", - "proxyQueryParams", "true")) - .build()); - // create policy - var membershipPolicy = "membership_policy_" + participantContextId; - managementApiClient.createPolicy(participantContextId, NewPolicyDefinition.Builder.aNewPolicyDefinition() - .id(membershipPolicy) - .policy(new PolicySet(List.of(new PolicySet.Permission("use", List.of(new PolicySet.Constraint("MembershipCredential", "eq", "active")))))) - .build()); - - // create contract definition - var membershipContractDef = "membership_contract_def_" + participantContextId; - managementApiClient.createContractDefinition(participantContextId, NewContractDefinition.Builder.aNewContractDefinition() - .id(membershipContractDef) - .accessPolicyId(membershipPolicy) - .contractPolicyId(membershipPolicy) - .assetsSelector(Set.of(new Criterion("privateProperties.'https://w3id.org/edc/v0.0.1/ns/permission'", - "=", permission))) - .build()); - } - - private record ParticipantInfo(String contextId, String webDid, Long id) { - } -}