diff --git a/extensions/wrapper/wrapper-api/src/main/java/de/sovity/edc/ext/wrapper/api/ui/model/DashboardPage.java b/extensions/wrapper/wrapper-api/src/main/java/de/sovity/edc/ext/wrapper/api/ui/model/DashboardPage.java index 9a3ece7e2..16b69fe61 100644 --- a/extensions/wrapper/wrapper-api/src/main/java/de/sovity/edc/ext/wrapper/api/ui/model/DashboardPage.java +++ b/extensions/wrapper/wrapper-api/src/main/java/de/sovity/edc/ext/wrapper/api/ui/model/DashboardPage.java @@ -15,6 +15,27 @@ @RequiredArgsConstructor public class DashboardPage { + @Schema(description = "Number of Assets", requiredMode = Schema.RequiredMode.REQUIRED) + private int numAssets; + + @Schema(description = "Number of Policies", requiredMode = Schema.RequiredMode.REQUIRED) + private int numPolicies; + + @Schema(description = "Number of Contract Definitions", requiredMode = Schema.RequiredMode.REQUIRED) + private int numContractDefinitions; + + @Schema(description = "Number of consuming Contract Agreements", requiredMode = Schema.RequiredMode.REQUIRED) + private long numContractAgreementsConsuming; + + @Schema(description = "Number of providing Contract Agreements", requiredMode = Schema.RequiredMode.REQUIRED) + private long numContractAgreementsProviding; + + @Schema(description = "Consuming Transfer Process Amounts", requiredMode = Schema.RequiredMode.REQUIRED) + private DashboardTransferAmounts transferProcessesConsuming; + + @Schema(description = "Providing Transfer Process Amounts", requiredMode = Schema.RequiredMode.REQUIRED) + private DashboardTransferAmounts transferProcessesProviding; + @Schema(description = "Your Connector's Connector Endpoint", requiredMode = Schema.RequiredMode.REQUIRED) private String connectorEndpoint; @@ -44,22 +65,4 @@ public class DashboardPage { @Schema(description = "Your Connector's MIW Configuration (if present)", requiredMode = Schema.RequiredMode.NOT_REQUIRED) private DashboardMiwConfig connectorMiwConfig; - - @Schema(description = "Providing Transfer Process Amounts", requiredMode = Schema.RequiredMode.REQUIRED) - private DashboardTransferAmounts providingTransferProcesses; - - @Schema(description = "Consuming Transfer Process Amounts", requiredMode = Schema.RequiredMode.REQUIRED) - private DashboardTransferAmounts consumingTransferProcesses; - - @Schema(description = "Number of Assets", requiredMode = Schema.RequiredMode.REQUIRED) - private int numberOfAssets; - - @Schema(description = "Number of Policies", requiredMode = Schema.RequiredMode.REQUIRED) - private int numberOfPolicies; - - @Schema(description = "Number of consuming Contract Agreements", requiredMode = Schema.RequiredMode.REQUIRED) - private long numberOfConsumingAgreements; - - @Schema(description = "Number of providing Contract Agreements", requiredMode = Schema.RequiredMode.REQUIRED) - private long numberOfProvidingAgreements; } diff --git a/extensions/wrapper/wrapper-api/src/main/java/de/sovity/edc/ext/wrapper/api/ui/model/DashboardTransferAmounts.java b/extensions/wrapper/wrapper-api/src/main/java/de/sovity/edc/ext/wrapper/api/ui/model/DashboardTransferAmounts.java index 2f11a103f..476491e78 100644 --- a/extensions/wrapper/wrapper-api/src/main/java/de/sovity/edc/ext/wrapper/api/ui/model/DashboardTransferAmounts.java +++ b/extensions/wrapper/wrapper-api/src/main/java/de/sovity/edc/ext/wrapper/api/ui/model/DashboardTransferAmounts.java @@ -14,6 +14,8 @@ @AllArgsConstructor @RequiredArgsConstructor public class DashboardTransferAmounts { + @Schema(description = "Number of Transfer Processes", requiredMode = Schema.RequiredMode.REQUIRED) + private long numTotal; @Schema(description = "Number of running Transfer Processes", requiredMode = Schema.RequiredMode.REQUIRED) private long numRunning; diff --git a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/WrapperExtensionContextBuilder.java b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/WrapperExtensionContextBuilder.java index c12cb84ae..32eda5b85 100644 --- a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/WrapperExtensionContextBuilder.java +++ b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/WrapperExtensionContextBuilder.java @@ -216,7 +216,8 @@ public static WrapperExtensionContext buildContext( contractNegotiationStore, transferProcessService, assetIndex, - policyDefinitionService + policyDefinitionService, + contractDefinitionService ); var dashboardApiService = new DashboardPageApiService( dashboardDataFetcher, diff --git a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/DashboardPageApiService.java b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/DashboardPageApiService.java index 18ad1a46c..fadf3601e 100644 --- a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/DashboardPageApiService.java +++ b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/DashboardPageApiService.java @@ -23,16 +23,21 @@ import de.sovity.edc.ext.wrapper.api.ui.pages.dashboard.services.SelfDescriptionService; import de.sovity.edc.ext.wrapper.api.ui.pages.transferhistory.TransferProcessStateService; import lombok.RequiredArgsConstructor; +import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreement; +import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation; import org.eclipse.edc.connector.transfer.spi.types.TransferProcess; import org.jetbrains.annotations.NotNull; import java.util.List; +import java.util.Objects; import java.util.Set; +import java.util.function.Predicate; import java.util.stream.Collectors; import static de.sovity.edc.ext.wrapper.api.ui.model.TransferProcessSimplifiedState.ERROR; import static de.sovity.edc.ext.wrapper.api.ui.model.TransferProcessSimplifiedState.OK; import static de.sovity.edc.ext.wrapper.api.ui.model.TransferProcessSimplifiedState.RUNNING; +import static java.util.stream.Collectors.toSet; @RequiredArgsConstructor public class DashboardPageApiService { @@ -44,24 +49,33 @@ public class DashboardPageApiService { @NotNull public DashboardPage dashboardPage() { - var transferProcesses = dashboardDataFetcher.getTransferProcesses(); var negotiations = dashboardDataFetcher.getAllContractNegotiations(); var providingAgreements = negotiations.stream() - .filter(negotiation -> ContractAgreementDirection.fromType(negotiation.getType()).equals(ContractAgreementDirection.PROVIDING)) - .filter(negotiation -> negotiation.getContractAgreement() != null) - .map(negotiation -> negotiation.getContractAgreement().getId()) - .collect(Collectors.toSet()); + .filter(it -> it.getType() == ContractNegotiation.Type.PROVIDER) + .map(ContractNegotiation::getContractAgreement) + .filter(Objects::nonNull) + .map(ContractAgreement::getId) + .collect(toSet()); var consumingAgreements = negotiations.stream() - .filter(negotiation -> ContractAgreementDirection.fromType(negotiation.getType()).equals(ContractAgreementDirection.CONSUMING)) - .filter(negotiation -> negotiation.getContractAgreement() != null) - .map(negotiation -> negotiation.getContractAgreement().getId()) - .collect(Collectors.toSet()); + .filter(it -> it.getType() == ContractNegotiation.Type.CONSUMER) + .map(ContractNegotiation::getContractAgreement) + .filter(Objects::nonNull) + .map(ContractAgreement::getId) + .collect(toSet()); DashboardPage dashboardPage = new DashboardPage(); + dashboardPage.setNumAssets(dashboardDataFetcher.getNumberOfAssets()); + dashboardPage.setNumPolicies(dashboardDataFetcher.getNumberOfPolicies()); + dashboardPage.setNumContractDefinitions(dashboardDataFetcher.getNumberOfContractDefinitions()); + dashboardPage.setNumContractAgreementsProviding(providingAgreements.size()); + dashboardPage.setNumContractAgreementsConsuming(consumingAgreements.size()); + dashboardPage.setTransferProcessesProviding(getTransferAmounts(transferProcesses, providingAgreements)); + dashboardPage.setTransferProcessesConsuming(getTransferAmounts(transferProcesses, consumingAgreements)); + dashboardPage.setConnectorTitle(selfDescriptionService.getConnectorTitle()); dashboardPage.setConnectorDescription(selfDescriptionService.getConnectorDescription()); dashboardPage.setConnectorEndpoint(selfDescriptionService.getConnectorEndpoint()); @@ -74,12 +88,6 @@ public DashboardPage dashboardPage() { dashboardPage.setConnectorMiwConfig(miwConfigService.buildMiwConfigOrNull()); dashboardPage.setConnectorDapsConfig(dapsConfigService.buildDapsConfigOrNull()); - dashboardPage.setNumberOfAssets(dashboardDataFetcher.getNumberOfAssets()); - dashboardPage.setNumberOfPolicies(dashboardDataFetcher.getNumberOfPolicies()); - dashboardPage.setProvidingTransferProcesses(getTransferAmounts(transferProcesses, providingAgreements)); - dashboardPage.setConsumingTransferProcesses(getTransferAmounts(transferProcesses, consumingAgreements)); - dashboardPage.setNumberOfProvidingAgreements(providingAgreements.size()); - dashboardPage.setNumberOfConsumingAgreements(consumingAgreements.size()); return dashboardPage; } @@ -87,21 +95,25 @@ DashboardTransferAmounts getTransferAmounts( List transferProcesses, Set agreements ) { + var numTotal = transferProcesses.stream() + .filter(transferProcess -> agreements.contains(transferProcess.getDataRequest().getContractId())) + .count(); + var numOk = transferProcesses.stream() - .filter(transferProcess -> transferProcessStateService.getSimplifiedState(transferProcess.getState()).equals(OK)) .filter(transferProcess -> agreements.contains(transferProcess.getDataRequest().getContractId())) + .filter(transferProcess -> transferProcessStateService.getSimplifiedState(transferProcess.getState()).equals(OK)) .count(); var numRunning = transferProcesses.stream() - .filter(transferProcess -> transferProcessStateService.getSimplifiedState(transferProcess.getState()).equals(RUNNING)) .filter(transferProcess -> agreements.contains(transferProcess.getDataRequest().getContractId())) + .filter(transferProcess -> transferProcessStateService.getSimplifiedState(transferProcess.getState()).equals(RUNNING)) .count(); var numError = transferProcesses.stream() - .filter(transferProcess -> transferProcessStateService.getSimplifiedState(transferProcess.getState()).equals(ERROR)) .filter(transferProcess -> agreements.contains(transferProcess.getDataRequest().getContractId())) + .filter(transferProcess -> transferProcessStateService.getSimplifiedState(transferProcess.getState()).equals(ERROR)) .count(); - return new DashboardTransferAmounts(numRunning, numOk, numError); + return new DashboardTransferAmounts(numTotal, numRunning, numOk, numError); } } diff --git a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/DashboardDataFetcher.java b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/DashboardDataFetcher.java index f0e542afe..0eee91dbc 100644 --- a/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/DashboardDataFetcher.java +++ b/extensions/wrapper/wrapper/src/main/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/services/DashboardDataFetcher.java @@ -18,6 +18,7 @@ import lombok.RequiredArgsConstructor; import org.eclipse.edc.connector.contract.spi.negotiation.store.ContractNegotiationStore; import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation; +import org.eclipse.edc.connector.spi.contractdefinition.ContractDefinitionService; import org.eclipse.edc.connector.spi.policydefinition.PolicyDefinitionService; import org.eclipse.edc.connector.spi.transferprocess.TransferProcessService; import org.eclipse.edc.connector.transfer.spi.types.TransferProcess; @@ -33,6 +34,7 @@ public class DashboardDataFetcher { private final TransferProcessService transferProcessService; private final AssetIndex assetIndex; private final PolicyDefinitionService policyDefinitionService; + private final ContractDefinitionService contractDefinitionService; public int getNumberOfAssets() { return assetIndex.queryAssets(QuerySpec.max()).toList().size(); @@ -44,6 +46,12 @@ public int getNumberOfPolicies() { .count()); } + public int getNumberOfContractDefinitions() { + return Math.toIntExact(contractDefinitionService.query(QuerySpec.max()) + .orElseThrow(ServiceException::new) + .count()); + } + @NotNull public List getAllContractNegotiations() { return contractNegotiationStore.queryNegotiations(QuerySpec.max()).toList(); diff --git a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/DashboardPageApiServiceTest.java b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/DashboardPageApiServiceTest.java index d21c0a5b3..543513525 100644 --- a/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/DashboardPageApiServiceTest.java +++ b/extensions/wrapper/wrapper/src/test/java/de/sovity/edc/ext/wrapper/api/ui/pages/dashboard/DashboardPageApiServiceTest.java @@ -19,7 +19,9 @@ import org.eclipse.edc.connector.contract.spi.negotiation.store.ContractNegotiationStore; import org.eclipse.edc.connector.contract.spi.types.agreement.ContractAgreement; import org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation; +import org.eclipse.edc.connector.contract.spi.types.offer.ContractDefinition; import org.eclipse.edc.connector.policy.spi.PolicyDefinition; +import org.eclipse.edc.connector.spi.contractdefinition.ContractDefinitionService; import org.eclipse.edc.connector.spi.policydefinition.PolicyDefinitionService; import org.eclipse.edc.connector.spi.transferprocess.TransferProcessService; import org.eclipse.edc.connector.transfer.spi.types.DataRequest; @@ -35,7 +37,11 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import java.util.Collection; import java.util.List; +import java.util.Random; +import java.util.function.Supplier; +import java.util.stream.IntStream; import static org.assertj.core.api.Assertions.assertThat; import static org.eclipse.edc.connector.contract.spi.types.negotiation.ContractNegotiation.Type.CONSUMER; @@ -52,6 +58,8 @@ class DashboardPageApiServiceTest { PolicyDefinitionService policyDefinitionService; TransferProcessService transferProcessService; ContractNegotiationStore contractNegotiationStore; + ContractDefinitionService contractDefinitionService; + private Random random; @BeforeEach void setUp(EdcExtension extension) { @@ -67,71 +75,65 @@ void setUp(EdcExtension extension) { contractNegotiationStore = mock(ContractNegotiationStore.class); extension.registerServiceMock(ContractNegotiationStore.class, contractNegotiationStore); + contractDefinitionService = mock(ContractDefinitionService.class); + extension.registerServiceMock(ContractDefinitionService.class, contractDefinitionService); + TestUtils.setupExtension(extension); client = TestUtils.edcClient(); + random = new Random(); } @Test - void testDashboardPage() { - + void testKpis() { // arrange - var assets = List.of( - dummyAsset(), - dummyAsset(), - dummyAsset(), - dummyAsset(), - dummyAsset(), - dummyAsset() - ); - var transferProcesses = List.of( - mockTransferProcess("test1", 1, TransferProcessStates.COMPLETED.code()), - mockTransferProcess("test2", 2, TransferProcessStates.TERMINATED.code()), - mockTransferProcess("test3", 3, TransferProcessStates.STARTED.code()), - mockTransferProcess("test4", 4, TransferProcessStates.DEPROVISIONED.code()), - mockTransferProcess("test5", 5, TransferProcessStates.TERMINATED.code()), - mockTransferProcess("test6", 6, TransferProcessStates.INITIAL.code()) - - ); - - var policyDefinitions = List.of( - mockPolicyDefinition(), - mockPolicyDefinition() + mockAmounts( + repeat(7, this::mockAsset), + repeat(8, this::mockPolicyDefinition), + repeat(9, this::mockContractDefinition), + List.of( + mockContractNegotiation(1, CONSUMER), + mockContractNegotiation(2, PROVIDER), + mockContractNegotiation(3, PROVIDER), + mockContractNegotiationInProgress(CONSUMER), + mockContractNegotiationInProgress(PROVIDER) + ), + flat(List.of( + repeat(1, () -> mockTransferProcess(1, TransferProcessStates.REQUESTING.code())), + repeat(2, () -> mockTransferProcess(1, TransferProcessStates.TERMINATED.code())), + repeat(3, () -> mockTransferProcess(1, TransferProcessStates.COMPLETED.code())), + repeat(4, () -> mockTransferProcess(2, TransferProcessStates.REQUESTING.code())), + repeat(5, () -> mockTransferProcess(2, TransferProcessStates.TERMINATED.code())), + repeat(6, () -> mockTransferProcess(2, TransferProcessStates.COMPLETED.code())) + )) ); - var contractNegotiations = List.of( - mockContractNegotiation(1, CONSUMER), - mockContractNegotiation(2, CONSUMER), - mockContractNegotiation(3, CONSUMER), - mockContractNegotiation(4, PROVIDER), - mockContractNegotiation(5, PROVIDER), - mockContractNegotiation(6, PROVIDER), - mockContractNegotiation(7, PROVIDER), - mockContractNegotiationInProgress(PROVIDER) - ); - - when(assetIndex.queryAssets(eq(QuerySpec.max()))).thenReturn(assets.stream()); - when(transferProcessService.query(eq(QuerySpec.max()))).thenReturn(ServiceResult.success(transferProcesses.stream())); - when(policyDefinitionService.query(eq(QuerySpec.max()))).thenReturn(ServiceResult.success(policyDefinitions.stream())); - when(contractNegotiationStore.queryNegotiations(eq(QuerySpec.max()))).thenReturn(contractNegotiations.stream()); + // act + var dashboardPage = client.uiApi().getDashboardPage(); + assertThat(dashboardPage.getNumAssets()).isEqualTo(7); + assertThat(dashboardPage.getNumPolicies()).isEqualTo(8); + assertThat(dashboardPage.getNumContractDefinitions()).isEqualTo(9); + assertThat(dashboardPage.getNumContractAgreementsConsuming()).isEqualTo(1); + assertThat(dashboardPage.getNumContractAgreementsProviding()).isEqualTo(2); + assertThat(dashboardPage.getTransferProcessesConsuming().getNumTotal()).isEqualTo(1 + 2 + 3); + assertThat(dashboardPage.getTransferProcessesConsuming().getNumRunning()).isEqualTo(1); + assertThat(dashboardPage.getTransferProcessesConsuming().getNumError()).isEqualTo(2); + assertThat(dashboardPage.getTransferProcessesConsuming().getNumOk()).isEqualTo(3); + assertThat(dashboardPage.getTransferProcessesProviding().getNumTotal()).isEqualTo(4 + 5 + 6); + assertThat(dashboardPage.getTransferProcessesProviding().getNumRunning()).isEqualTo(4); + assertThat(dashboardPage.getTransferProcessesProviding().getNumError()).isEqualTo(5); + assertThat(dashboardPage.getTransferProcessesProviding().getNumOk()).isEqualTo(6); + } + @Test + void testConnectorMetadata() { + // arrange + mockAmounts(List.of(), List.of(), List.of(), List.of(), List.of()); // act var dashboardPage = client.uiApi().getDashboardPage(); // assert - assertThat(dashboardPage.getNumberOfAssets()).isEqualTo(assets.size()); - assertThat(dashboardPage.getNumberOfPolicies()).isEqualTo(policyDefinitions.size()); - assertThat(dashboardPage.getNumberOfConsumingAgreements()).isEqualTo(3); - assertThat(dashboardPage.getNumberOfProvidingAgreements()).isEqualTo(4); - assertThat(dashboardPage.getConsumingTransferProcesses().getNumOk()).isEqualTo(1); - assertThat(dashboardPage.getProvidingTransferProcesses().getNumOk()).isEqualTo(1); - assertThat(dashboardPage.getConsumingTransferProcesses().getNumError()).isEqualTo(1); - assertThat(dashboardPage.getProvidingTransferProcesses().getNumError()).isEqualTo(1); - assertThat(dashboardPage.getConsumingTransferProcesses().getNumRunning()).isEqualTo(1); - assertThat(dashboardPage.getProvidingTransferProcesses().getNumRunning()).isEqualTo(1); - - //test Connector Properties assertThat(dashboardPage.getConnectorParticipantId()).isEqualTo("my-edc-participant-id"); assertThat(dashboardPage.getConnectorDescription()).isEqualTo("My Connector Description"); assertThat(dashboardPage.getConnectorTitle()).isEqualTo("My Connector"); @@ -140,27 +142,18 @@ void testDashboardPage() { assertThat(dashboardPage.getConnectorCuratorUrl()).isEqualTo("https://connector.my-org"); assertThat(dashboardPage.getConnectorMaintainerName()).isEqualTo("Maintainer Org"); assertThat(dashboardPage.getConnectorMaintainerUrl()).isEqualTo("https://maintainer-org"); + assertThat(dashboardPage.getConnectorDapsConfig()).isNotNull(); assertThat(dashboardPage.getConnectorDapsConfig().getTokenUrl()).isEqualTo("https://token-url.daps"); assertThat(dashboardPage.getConnectorDapsConfig().getJwksUrl()).isEqualTo("https://jwks-url.daps"); + assertThat(dashboardPage.getConnectorMiwConfig()).isNotNull(); assertThat(dashboardPage.getConnectorMiwConfig().getAuthorityId()).isEqualTo("my-authority-id"); assertThat(dashboardPage.getConnectorMiwConfig().getUrl()).isEqualTo("https://miw"); assertThat(dashboardPage.getConnectorMiwConfig().getTokenUrl()).isEqualTo("https://token.miw"); } - private TransferProcess mockTransferProcess(String id, int contractId, int state) { - DataRequest dataRequest = mock(DataRequest.class); - when(dataRequest.getContractId()).thenReturn("ca-" + contractId); - - TransferProcess transferProcess = mock(TransferProcess.class); - when(transferProcess.getId()).thenReturn(id); - when(transferProcess.getDataRequest()).thenReturn(dataRequest); - when(transferProcess.getState()).thenReturn(state); - return transferProcess; - } - - private Asset dummyAsset() { + private Asset mockAsset() { return mock(Asset.class); } @@ -168,7 +161,11 @@ private PolicyDefinition mockPolicyDefinition() { return mock(PolicyDefinition.class); } - private ContractNegotiation mockContractNegotiation(int contract, ContractNegotiation.Type type ) { + private ContractDefinition mockContractDefinition() { + return mock(ContractDefinition.class); + } + + private ContractNegotiation mockContractNegotiation(int contract, ContractNegotiation.Type type) { var contractAgreement = mock(ContractAgreement.class); when(contractAgreement.getId()).thenReturn("ca-" + contract); @@ -184,4 +181,41 @@ private ContractNegotiation mockContractNegotiationInProgress(ContractNegotiatio when(contractNegotiation.getType()).thenReturn(type); return contractNegotiation; } + + private TransferProcess mockTransferProcess(int contractId, int state) { + DataRequest dataRequest = mock(DataRequest.class); + when(dataRequest.getContractId()).thenReturn("ca-" + contractId); + + TransferProcess transferProcess = mock(TransferProcess.class); + when(transferProcess.getId()).thenReturn(String.valueOf(random.nextInt())); + when(transferProcess.getDataRequest()).thenReturn(dataRequest); + when(transferProcess.getState()).thenReturn(state); + return transferProcess; + } + + private void mockAmounts( + List assets, + List policyDefinitions, + List contractDefinitions, + List contractNegotiations, + List transferProcesses + ) { + when(assetIndex.queryAssets(eq(QuerySpec.max()))).thenAnswer(i -> assets.stream()); + when(transferProcessService.query(eq(QuerySpec.max()))) + .thenAnswer(i -> ServiceResult.success(transferProcesses.stream())); + when(policyDefinitionService.query(eq(QuerySpec.max()))) + .thenAnswer(i -> ServiceResult.success(policyDefinitions.stream())); + when(contractNegotiationStore.queryNegotiations(eq(QuerySpec.max()))) + .thenAnswer(i -> contractNegotiations.stream()); + when(contractDefinitionService.query(eq(QuerySpec.max()))) + .thenAnswer(i -> ServiceResult.success(contractDefinitions.stream())); + } + + private List repeat(int times, Supplier supplier) { + return IntStream.range(0, times).mapToObj(i -> supplier.get()).toList(); + } + + private List flat(Collection> collections) { + return collections.stream().flatMap(Collection::stream).toList(); + } }