From 22cee69bca2eaaadb3d1eedf3bba1c4dbbb85097 Mon Sep 17 00:00:00 2001 From: "enrico.peroglio" Date: Fri, 23 Jan 2026 11:49:17 +0100 Subject: [PATCH 1/8] feat: first coding --- .../api/dto/response/PartnerReference.java | 4 +- .../domain/entity/PartnerReference.java | 28 +++++++++++- .../redline/domain/service/TenantService.java | 2 +- .../service/TenantServiceIntegrationTest.java | 44 +++++++++++++++++-- 4 files changed, 72 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/metaformsystems/redline/api/dto/response/PartnerReference.java b/src/main/java/com/metaformsystems/redline/api/dto/response/PartnerReference.java index ba11021..28d5e3d 100644 --- a/src/main/java/com/metaformsystems/redline/api/dto/response/PartnerReference.java +++ b/src/main/java/com/metaformsystems/redline/api/dto/response/PartnerReference.java @@ -14,5 +14,7 @@ package com.metaformsystems.redline.api.dto.response; -public record PartnerReference(String identifier, String nickname) { +import java.util.Map; + +public record PartnerReference(String identifier, String nickname, Map properties) { } diff --git a/src/main/java/com/metaformsystems/redline/domain/entity/PartnerReference.java b/src/main/java/com/metaformsystems/redline/domain/entity/PartnerReference.java index 7574076..277d863 100644 --- a/src/main/java/com/metaformsystems/redline/domain/entity/PartnerReference.java +++ b/src/main/java/com/metaformsystems/redline/domain/entity/PartnerReference.java @@ -14,11 +14,37 @@ package com.metaformsystems.redline.domain.entity; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; import jakarta.persistence.Embeddable; +import java.util.HashMap; +import java.util.Map; + /** * A reference to a partner organization. The identifier is the participant identifier such as a DID. */ @Embeddable -public record PartnerReference(String identifier, String nickname) { +public record PartnerReference( + @Column(name = "identifier") + String identifier, + + @Column(name = "nickname") + String nickname, + + @Column(name = "properties", columnDefinition = "TEXT") + @Convert(converter = HashMapConverter.class) + Map properties +) { + public PartnerReference { + // Canonical constructor - initialize properties if null + if (properties == null) { + properties = new HashMap<>(); + } + } + + // Convenience constructor for backward compatibility + public PartnerReference(String identifier, String nickname) { + this(identifier, nickname, new HashMap<>()); + } } diff --git a/src/main/java/com/metaformsystems/redline/domain/service/TenantService.java b/src/main/java/com/metaformsystems/redline/domain/service/TenantService.java index c545ef2..cc25ad8 100644 --- a/src/main/java/com/metaformsystems/redline/domain/service/TenantService.java +++ b/src/main/java/com/metaformsystems/redline/domain/service/TenantService.java @@ -214,7 +214,7 @@ public List getPartnerReferences(Long participantId, Long data .flatMap(p -> p.getDataspaceInfos().stream()) .filter(i -> i.getDataspaceId().equals(dataspacesId)) .flatMap(i -> i.getPartners().stream()) - .map(r -> new PartnerReference(r.identifier(), r.nickname())) + .map(r -> new PartnerReference(r.identifier(), r.nickname(), r.properties())) .toList(); } diff --git a/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java b/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java index 84810b2..58ab88b 100644 --- a/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java +++ b/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java @@ -454,8 +454,40 @@ void shouldGetPartnerReferences() { var participant = participantRepository.findById(participantId).orElseThrow(); var dataspaceInfo = participant.getDataspaceInfos().iterator().next(); var references = new ArrayList(); + var partner1Properties = Map.of("key1", "value1", "key2", 123); + var partner2Properties = Map.of("key3", "value3"); + references.add(new PartnerReference("did:web:partner1.com", "Partner One", partner1Properties)); + references.add(new PartnerReference("did:web:partner2.com", "Partner Two", partner2Properties)); + dataspaceInfo.setPartners(references); + participantRepository.save(participant); + + + var result = tenantService.getPartnerReferences(participantId, dataspace.getId()); + + + assertThat(result).hasSize(2); + assertThat(result).anyMatch(ref -> ref.identifier().equals("did:web:partner1.com") + && ref.nickname().equals("Partner One") + && ref.properties().equals(partner1Properties)); + assertThat(result).anyMatch(ref -> ref.identifier().equals("did:web:partner2.com") + && ref.nickname().equals("Partner Two") + && ref.properties().equals(partner2Properties)); + } + + @Test + void shouldGetPartnerReferences_withEmptyProperties() { + + var infos = List.of(new DataspaceInfo(dataspace.getId(), List.of(), List.of(), Map.of())); + var registration = new TenantRegistration("Test Tenant", infos); + var tenant = tenantService.registerTenant(serviceProvider.getId(), registration); + var participantId = tenant.participants().iterator().next().id(); + + // Add partners to the participant's dataspace info with empty properties + var participant = participantRepository.findById(participantId).orElseThrow(); + var dataspaceInfo = participant.getDataspaceInfos().iterator().next(); + var references = new ArrayList(); references.add(new PartnerReference("did:web:partner1.com", "Partner One")); - references.add(new PartnerReference("did:web:partner2.com", "Partner Two")); + references.add(new PartnerReference("did:web:partner2.com", "Partner Two", Map.of())); dataspaceInfo.setPartners(references); participantRepository.save(participant); @@ -464,8 +496,14 @@ void shouldGetPartnerReferences() { assertThat(result).hasSize(2); - assertThat(result).anyMatch(ref -> ref.identifier().equals("did:web:partner1.com") && ref.nickname().equals("Partner One")); - assertThat(result).anyMatch(ref -> ref.identifier().equals("did:web:partner2.com") && ref.nickname().equals("Partner Two")); + assertThat(result).anyMatch(ref -> ref.identifier().equals("did:web:partner1.com") + && ref.nickname().equals("Partner One") + && ref.properties() != null + && ref.properties().isEmpty()); + assertThat(result).anyMatch(ref -> ref.identifier().equals("did:web:partner2.com") + && ref.nickname().equals("Partner Two") + && ref.properties() != null + && ref.properties().isEmpty()); } } From f4edab4b2b65d1b1165258dc97ee73da0629c6fb Mon Sep 17 00:00:00 2001 From: "enrico.peroglio" Date: Fri, 23 Jan 2026 12:42:43 +0100 Subject: [PATCH 2/8] fix: removed @Column --- .../redline/domain/entity/PartnerReference.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/com/metaformsystems/redline/domain/entity/PartnerReference.java b/src/main/java/com/metaformsystems/redline/domain/entity/PartnerReference.java index 277d863..9c59cc0 100644 --- a/src/main/java/com/metaformsystems/redline/domain/entity/PartnerReference.java +++ b/src/main/java/com/metaformsystems/redline/domain/entity/PartnerReference.java @@ -26,12 +26,9 @@ */ @Embeddable public record PartnerReference( - @Column(name = "identifier") String identifier, - - @Column(name = "nickname") String nickname, - + @Column(name = "properties", columnDefinition = "TEXT") @Convert(converter = HashMapConverter.class) Map properties From f46c0b1413a844b417194612565b4f924ca416f5 Mon Sep 17 00:00:00 2001 From: "enrico.peroglio" Date: Fri, 23 Jan 2026 16:09:43 +0100 Subject: [PATCH 3/8] feat: added Partner creation --- .../api/controller/TenantController.java | 24 +++ .../dto/request/PartnerReferenceRequest.java | 30 ++++ .../redline/domain/service/TenantService.java | 37 +++++ .../TenantControllerIntegrationTest.java | 95 ++++++++++++ .../service/TenantServiceIntegrationTest.java | 140 ++++++++++++++++++ 5 files changed, 326 insertions(+) create mode 100644 src/main/java/com/metaformsystems/redline/api/dto/request/PartnerReferenceRequest.java diff --git a/src/main/java/com/metaformsystems/redline/api/controller/TenantController.java b/src/main/java/com/metaformsystems/redline/api/controller/TenantController.java index 42d6cb5..806d0d8 100644 --- a/src/main/java/com/metaformsystems/redline/api/controller/TenantController.java +++ b/src/main/java/com/metaformsystems/redline/api/controller/TenantController.java @@ -16,6 +16,7 @@ import com.metaformsystems.redline.api.dto.request.DataPlaneRegistrationRequest; import com.metaformsystems.redline.api.dto.request.ParticipantDeployment; +import com.metaformsystems.redline.api.dto.request.PartnerReferenceRequest; import com.metaformsystems.redline.api.dto.request.ServiceProvider; import com.metaformsystems.redline.api.dto.request.TenantRegistration; import com.metaformsystems.redline.api.dto.response.Dataspace; @@ -202,6 +203,29 @@ public ResponseEntity> getPartners(@PathVariable Long pro return ResponseEntity.ok(references); } + @PostMapping("service-providers/{providerId}/tenants/{tenantId}/participants/{participantId}/partners/{dataspaceId}") +// @PreAuthorize("hasRole('USER')") + @Operation(summary = "Create partner reference", description = "Creates a new partner reference for a participant in a specific dataspace") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Partner reference successfully created", + content = @Content(schema = @Schema(implementation = PartnerReference.class))), + @ApiResponse(responseCode = "400", description = "Invalid partner reference data"), + @ApiResponse(responseCode = "404", description = "Service provider, tenant, participant, or dataspace not found") + }) + @Parameter(name = "providerId", description = "Database ID of the service provider", required = true) + @Parameter(name = "tenantId", description = "Database ID of the tenant", required = true) + @Parameter(name = "participantId", description = "Database ID of the participant", required = true) + @Parameter(name = "dataspaceId", description = "Database ID of the dataspace", required = true) + public ResponseEntity createPartner(@PathVariable Long providerId, + @PathVariable Long tenantId, + @PathVariable Long participantId, + @PathVariable Long dataspaceId, + @RequestBody PartnerReferenceRequest request) { + var partnerReference = tenantService.createPartnerReference(providerId, tenantId, participantId, dataspaceId, request); + // TODO auth check for provider access + return ResponseEntity.ok(partnerReference); + } + @GetMapping("service-providers/{serviceProviderId}/tenants/{tenantId}/participants/{participantId}/dataspaces") // @PreAuthorize("hasRole('USER')") @Operation(summary = "Get participant dataspaces", description = "Retrieves a list of dataspaces associated with a specific participant") diff --git a/src/main/java/com/metaformsystems/redline/api/dto/request/PartnerReferenceRequest.java b/src/main/java/com/metaformsystems/redline/api/dto/request/PartnerReferenceRequest.java new file mode 100644 index 0000000..7f61fa7 --- /dev/null +++ b/src/main/java/com/metaformsystems/redline/api/dto/request/PartnerReferenceRequest.java @@ -0,0 +1,30 @@ +/* + * 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.api.dto.request; + +import java.util.Map; + +/** + * Request DTO for creating a partner reference. + */ +public record PartnerReferenceRequest( + String identifier, + String nickname, + Map properties +) { + public PartnerReferenceRequest(String identifier, String nickname) { + this(identifier, nickname, Map.of()); + } +} diff --git a/src/main/java/com/metaformsystems/redline/domain/service/TenantService.java b/src/main/java/com/metaformsystems/redline/domain/service/TenantService.java index d3bac26..ef8933d 100644 --- a/src/main/java/com/metaformsystems/redline/domain/service/TenantService.java +++ b/src/main/java/com/metaformsystems/redline/domain/service/TenantService.java @@ -16,6 +16,7 @@ import com.metaformsystems.redline.api.dto.request.DataPlaneRegistrationRequest; import com.metaformsystems.redline.api.dto.request.ParticipantDeployment; +import com.metaformsystems.redline.api.dto.request.PartnerReferenceRequest; import com.metaformsystems.redline.api.dto.request.TenantRegistration; import com.metaformsystems.redline.api.dto.response.Dataspace; import com.metaformsystems.redline.api.dto.response.Participant; @@ -218,6 +219,42 @@ public Participant getParticipant(Long id) { return toParticipantResource(profile); } + @Transactional + public PartnerReference createPartnerReference(Long providerId, Long tenantId, Long participantId, Long dataspaceId, PartnerReferenceRequest request) { + // Find participant first + var participant = participantRepository.findById(participantId) + .orElseThrow(() -> new ObjectNotFoundException("Participant not found with id: " + participantId)); + + // Verify participant belongs to the specified tenant + if (participant.getTenant() == null || !participant.getTenant().getId().equals(tenantId)) { + throw new ObjectNotFoundException("Participant " + participantId + " does not belong to tenant " + tenantId); + } + + // Verify tenant belongs to the specified service provider + var tenant = participant.getTenant(); + if (tenant.getServiceProvider() == null || !tenant.getServiceProvider().getId().equals(providerId)) { + throw new ObjectNotFoundException("Tenant " + tenantId + " does not belong to service provider " + providerId); + } + + // Find dataspace info + var dataspaceInfo = participant.getDataspaceInfos().stream() + .filter(i -> i.getDataspaceId().equals(dataspaceId)) + .findFirst() + .orElseThrow(() -> new ObjectNotFoundException("Dataspace info not found for participant " + participantId + " and dataspace " + dataspaceId)); + + // Create and add partner reference + var partnerReference = new com.metaformsystems.redline.domain.entity.PartnerReference( + request.identifier(), + request.nickname(), + request.properties() != null ? request.properties() : new java.util.HashMap<>() + ); + + dataspaceInfo.getPartners().add(partnerReference); + participantRepository.save(participant); + + return new PartnerReference(partnerReference.identifier(), partnerReference.nickname(), partnerReference.properties()); + } + @Transactional public List getPartnerReferences(Long participantId, Long dataspacesId) { return participantRepository.findById(participantId).stream() diff --git a/src/test/java/com/metaformsystems/redline/api/controller/TenantControllerIntegrationTest.java b/src/test/java/com/metaformsystems/redline/api/controller/TenantControllerIntegrationTest.java index 0dc9697..02d7191 100644 --- a/src/test/java/com/metaformsystems/redline/api/controller/TenantControllerIntegrationTest.java +++ b/src/test/java/com/metaformsystems/redline/api/controller/TenantControllerIntegrationTest.java @@ -17,6 +17,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.metaformsystems.redline.api.dto.request.DataspaceInfo; import com.metaformsystems.redline.api.dto.request.ParticipantDeployment; +import com.metaformsystems.redline.api.dto.request.PartnerReferenceRequest; import com.metaformsystems.redline.api.dto.request.ServiceProvider; import com.metaformsystems.redline.api.dto.request.TenantRegistration; import com.metaformsystems.redline.application.service.TokenProvider; @@ -480,6 +481,100 @@ void shouldGetParticipantDataspaces_withMultipleDataspaces() throws Exception { .andExpect(jsonPath("$[*].name").value(org.hamcrest.Matchers.containsInAnyOrder("Test Dataspace", "Second Dataspace"))); } + @Test + void shouldCreatePartnerReference() throws Exception { + // Create a tenant and participant with dataspace info + var tenant = new Tenant(); + tenant.setName("Test Tenant"); + tenant.setServiceProvider(serviceProvider); + tenant = tenantRepository.save(tenant); + + var participant = new Participant(); + participant.setIdentifier("Test Participant"); + participant.setTenant(tenant); + + // Add dataspace info to participant + var dataspaceInfo = new com.metaformsystems.redline.domain.entity.DataspaceInfo(); + dataspaceInfo.setDataspaceId(dataspace.getId()); + participant.getDataspaceInfos().add(dataspaceInfo); + + tenant.addParticipant(participant); + participant = participantRepository.save(participant); + + var request = new PartnerReferenceRequest("did:web:partner.com", "Partner Name", Map.of("key", "value")); + + mockMvc.perform(post("/api/ui/service-providers/{providerId}/tenants/{tenantId}/participants/{participantId}/partners/{dataspaceId}", + serviceProvider.getId(), tenant.getId(), participant.getId(), dataspace.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.identifier").value("did:web:partner.com")) + .andExpect(jsonPath("$.nickname").value("Partner Name")) + .andExpect(jsonPath("$.properties.key").value("value")); + + // Verify partner was saved + var savedParticipant = participantRepository.findById(participant.getId()).orElseThrow(); + var savedDataspaceInfo = savedParticipant.getDataspaceInfos().iterator().next(); + assertThat(savedDataspaceInfo.getPartners()).hasSize(1); + assertThat(savedDataspaceInfo.getPartners().get(0).identifier()).isEqualTo("did:web:partner.com"); + assertThat(savedDataspaceInfo.getPartners().get(0).nickname()).isEqualTo("Partner Name"); + } + + @Test + void shouldCreatePartnerReference_withProperties() throws Exception { + // Create a tenant and participant with dataspace info + var tenant = new Tenant(); + tenant.setName("Test Tenant"); + tenant.setServiceProvider(serviceProvider); + tenant = tenantRepository.save(tenant); + + var participant = new Participant(); + participant.setIdentifier("Test Participant"); + participant.setTenant(tenant); + + var dataspaceInfo = new com.metaformsystems.redline.domain.entity.DataspaceInfo(); + dataspaceInfo.setDataspaceId(dataspace.getId()); + participant.getDataspaceInfos().add(dataspaceInfo); + + tenant.addParticipant(participant); + participant = participantRepository.save(participant); + + var properties = Map.of( + "region", "EU", + "compliance", "GDPR", + "metadata", Map.of("createdBy", "admin", "tags", List.of("partner", "trusted")) + ); + var request = new PartnerReferenceRequest("did:web:partner.com", "Partner Name", properties); + + mockMvc.perform(post("/api/ui/service-providers/{providerId}/tenants/{tenantId}/participants/{participantId}/partners/{dataspaceId}", + serviceProvider.getId(), tenant.getId(), participant.getId(), dataspace.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.identifier").value("did:web:partner.com")) + .andExpect(jsonPath("$.nickname").value("Partner Name")) + .andExpect(jsonPath("$.properties.region").value("EU")) + .andExpect(jsonPath("$.properties.compliance").value("GDPR")); + } + + @Test + void shouldCreatePartnerReference_whenParticipantNotFound() throws Exception { + var tenant = new Tenant(); + tenant.setName("Test Tenant"); + tenant.setServiceProvider(serviceProvider); + tenant = tenantRepository.save(tenant); + + var request = new PartnerReferenceRequest("did:web:partner.com", "Partner Name"); + + mockMvc.perform(post("/api/ui/service-providers/{providerId}/tenants/{tenantId}/participants/{participantId}/partners/{dataspaceId}", + serviceProvider.getId(), tenant.getId(), 999L, dataspace.getId()) + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isNotFound()) + .andExpect(jsonPath("$.code").value(404)) + .andExpect(jsonPath("$.message").value(org.hamcrest.Matchers.containsString("Participant not found"))); + } + @Test void shouldGetParticipantDataspaces_whenParticipantNotFound() throws Exception { // Create a tenant without participant diff --git a/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java b/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java index f87c9c4..84408bf 100644 --- a/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java +++ b/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java @@ -16,6 +16,7 @@ import com.metaformsystems.redline.api.dto.request.DataspaceInfo; import com.metaformsystems.redline.api.dto.request.ParticipantDeployment; +import com.metaformsystems.redline.api.dto.request.PartnerReferenceRequest; import com.metaformsystems.redline.api.dto.request.TenantRegistration; import com.metaformsystems.redline.api.dto.response.VirtualParticipantAgent; import com.metaformsystems.redline.application.service.TokenProvider; @@ -587,6 +588,145 @@ void shouldGetParticipantDataspaces_whenNoDataspaces() { assertThat(result).isEmpty(); } + @Test + void shouldCreatePartnerReference() { + var infos = List.of(new DataspaceInfo(dataspace.getId(), List.of(), List.of(), Map.of())); + var registration = new TenantRegistration("Test Tenant", infos); + var tenant = tenantService.registerTenant(serviceProvider.getId(), registration); + var participantId = tenant.participants().iterator().next().id(); + + var request = new PartnerReferenceRequest("did:web:partner.com", "Partner Name", Map.of("key", "value")); + + var result = tenantService.createPartnerReference(serviceProvider.getId(), tenant.id(), participantId, dataspace.getId(), request); + + assertThat(result).isNotNull(); + assertThat(result.identifier()).isEqualTo("did:web:partner.com"); + assertThat(result.nickname()).isEqualTo("Partner Name"); + assertThat(result.properties()).containsEntry("key", "value"); + + // Verify partner was saved in database + var participant = participantRepository.findById(participantId).orElseThrow(); + var dataspaceInfo = participant.getDataspaceInfos().iterator().next(); + assertThat(dataspaceInfo.getPartners()).hasSize(1); + assertThat(dataspaceInfo.getPartners().get(0).identifier()).isEqualTo("did:web:partner.com"); + assertThat(dataspaceInfo.getPartners().get(0).nickname()).isEqualTo("Partner Name"); + } + + @Test + void shouldCreatePartnerReference_withProperties() { + var infos = List.of(new DataspaceInfo(dataspace.getId(), List.of(), List.of(), Map.of())); + var registration = new TenantRegistration("Test Tenant", infos); + var tenant = tenantService.registerTenant(serviceProvider.getId(), registration); + var participantId = tenant.participants().iterator().next().id(); + + var properties = Map.of( + "region", "EU", + "compliance", "GDPR", + "active", true + ); + var request = new PartnerReferenceRequest("did:web:partner.com", "Partner Name", properties); + + var result = tenantService.createPartnerReference(serviceProvider.getId(), tenant.id(), participantId, dataspace.getId(), request); + + assertThat(result).isNotNull(); + assertThat(result.properties()).containsEntry("region", "EU"); + assertThat(result.properties()).containsEntry("compliance", "GDPR"); + assertThat(result.properties()).containsEntry("active", true); + } + + @Test + void shouldCreatePartnerReference_withoutProperties() { + var infos = List.of(new DataspaceInfo(dataspace.getId(), List.of(), List.of(), Map.of())); + var registration = new TenantRegistration("Test Tenant", infos); + var tenant = tenantService.registerTenant(serviceProvider.getId(), registration); + var participantId = tenant.participants().iterator().next().id(); + + var request = new PartnerReferenceRequest("did:web:partner.com", "Partner Name"); + + var result = tenantService.createPartnerReference(serviceProvider.getId(), tenant.id(), participantId, dataspace.getId(), request); + + assertThat(result).isNotNull(); + assertThat(result.identifier()).isEqualTo("did:web:partner.com"); + assertThat(result.nickname()).isEqualTo("Partner Name"); + assertThat(result.properties()).isNotNull(); + assertThat(result.properties()).isEmpty(); + } + + @Test + void shouldCreatePartnerReference_whenParticipantNotFound() { + var infos = List.of(new DataspaceInfo(dataspace.getId(), List.of(), List.of(), Map.of())); + var registration = new TenantRegistration("Test Tenant", infos); + var tenant = tenantService.registerTenant(serviceProvider.getId(), registration); + + var request = new PartnerReferenceRequest("did:web:partner.com", "Partner Name"); + + assertThat(org.assertj.core.api.Assertions.catchThrowable(() -> + tenantService.createPartnerReference(serviceProvider.getId(), tenant.id(), 999L, dataspace.getId(), request))) + .isInstanceOf(ObjectNotFoundException.class) + .hasMessageContaining("Participant not found with id: 999"); + } + + @Test + void shouldCreatePartnerReference_whenParticipantDoesNotBelongToTenant() { + var infos1 = List.of(new DataspaceInfo(dataspace.getId(), List.of(), List.of(), Map.of())); + var registration1 = new TenantRegistration("Tenant One", infos1); + var tenant1 = tenantService.registerTenant(serviceProvider.getId(), registration1); + var participantId = tenant1.participants().iterator().next().id(); + + var infos2 = List.of(new DataspaceInfo(dataspace.getId(), List.of(), List.of(), Map.of())); + var registration2 = new TenantRegistration("Tenant Two", infos2); + var tenant2 = tenantService.registerTenant(serviceProvider.getId(), registration2); + + var request = new PartnerReferenceRequest("did:web:partner.com", "Partner Name"); + + assertThat(org.assertj.core.api.Assertions.catchThrowable(() -> + tenantService.createPartnerReference(serviceProvider.getId(), tenant2.id(), participantId, dataspace.getId(), request))) + .isInstanceOf(ObjectNotFoundException.class) + .hasMessageContaining("does not belong to tenant"); + } + + @Test + void shouldCreatePartnerReference_whenTenantDoesNotBelongToProvider() { + // Create another service provider + var otherProvider = new ServiceProvider(); + otherProvider.setName("Other Provider"); + otherProvider = serviceProviderRepository.save(otherProvider); + + var infos = List.of(new DataspaceInfo(dataspace.getId(), List.of(), List.of(), Map.of())); + var registration = new TenantRegistration("Test Tenant", infos); + var tenant = tenantService.registerTenant(otherProvider.getId(), registration); + var participantId = tenant.participants().iterator().next().id(); + + var request = new PartnerReferenceRequest("did:web:partner.com", "Partner Name"); + + assertThat(org.assertj.core.api.Assertions.catchThrowable(() -> + tenantService.createPartnerReference(serviceProvider.getId(), tenant.id(), participantId, dataspace.getId(), request))) + .isInstanceOf(ObjectNotFoundException.class) + .hasMessageContaining("does not belong to service provider"); + } + + @Test + void shouldCreatePartnerReference_whenDataspaceInfoNotFound() { + final var tenant = new Tenant(); + tenant.setName("Test Tenant"); + tenant.setServiceProvider(serviceProvider); + final var savedTenant = tenantRepository.save(tenant); + + final var participant = new Participant(); + participant.setIdentifier("Test Participant"); + participant.setTenant(savedTenant); + // No dataspace info added + savedTenant.addParticipant(participant); + final var savedParticipant = participantRepository.save(participant); + + var request = new PartnerReferenceRequest("did:web:partner.com", "Partner Name"); + + assertThat(org.assertj.core.api.Assertions.catchThrowable(() -> + tenantService.createPartnerReference(serviceProvider.getId(), savedTenant.getId(), savedParticipant.getId(), dataspace.getId(), request))) + .isInstanceOf(ObjectNotFoundException.class) + .hasMessageContaining("Dataspace info not found"); + } + @Test void shouldGetParticipantDataspaces_whenParticipantNotFound() { // Test with non-existent participant ID From 9f7c0fa3bd22d18ca1cc877507a99828d525711b Mon Sep 17 00:00:00 2001 From: Enrico Peroglio <96304477+enryp@users.noreply.github.com> Date: Mon, 26 Jan 2026 09:58:05 +0100 Subject: [PATCH 4/8] Update src/test/java/com/metaformsystems/redline/api/controller/TenantControllerIntegrationTest.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Of course, you’re absolutely right — sorry about that! I’ll fix it right away. Co-authored-by: Tim Dahlmanns <13997715+timdah@users.noreply.github.com> --- .../redline/api/controller/TenantControllerIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/metaformsystems/redline/api/controller/TenantControllerIntegrationTest.java b/src/test/java/com/metaformsystems/redline/api/controller/TenantControllerIntegrationTest.java index 02d7191..a69ef99 100644 --- a/src/test/java/com/metaformsystems/redline/api/controller/TenantControllerIntegrationTest.java +++ b/src/test/java/com/metaformsystems/redline/api/controller/TenantControllerIntegrationTest.java @@ -558,7 +558,7 @@ void shouldCreatePartnerReference_withProperties() throws Exception { } @Test - void shouldCreatePartnerReference_whenParticipantNotFound() throws Exception { + void shouldNotCreatePartnerReference_whenParticipantNotFound() throws Exception { var tenant = new Tenant(); tenant.setName("Test Tenant"); tenant.setServiceProvider(serviceProvider); From cc0ff8c326f21c5a0199b707e118a4f0edf97340 Mon Sep 17 00:00:00 2001 From: Enrico Peroglio <96304477+enryp@users.noreply.github.com> Date: Mon, 26 Jan 2026 09:59:24 +0100 Subject: [PATCH 5/8] Update src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java fix: test naming Co-authored-by: Tim Dahlmanns <13997715+timdah@users.noreply.github.com> --- .../redline/domain/service/TenantServiceIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java b/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java index 84408bf..a3507c1 100644 --- a/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java +++ b/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java @@ -653,7 +653,7 @@ void shouldCreatePartnerReference_withoutProperties() { } @Test - void shouldCreatePartnerReference_whenParticipantNotFound() { + void shouldNotCreatePartnerReference_whenParticipantNotFound() { var infos = List.of(new DataspaceInfo(dataspace.getId(), List.of(), List.of(), Map.of())); var registration = new TenantRegistration("Test Tenant", infos); var tenant = tenantService.registerTenant(serviceProvider.getId(), registration); From 89a4dddf9cdece235f58f0d3412816d93e1ff4d3 Mon Sep 17 00:00:00 2001 From: Enrico Peroglio <96304477+enryp@users.noreply.github.com> Date: Mon, 26 Jan 2026 09:59:46 +0100 Subject: [PATCH 6/8] Update src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java fix: test naming Co-authored-by: Tim Dahlmanns <13997715+timdah@users.noreply.github.com> --- .../redline/domain/service/TenantServiceIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java b/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java index a3507c1..55bbc33 100644 --- a/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java +++ b/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java @@ -667,7 +667,7 @@ void shouldNotCreatePartnerReference_whenParticipantNotFound() { } @Test - void shouldCreatePartnerReference_whenParticipantDoesNotBelongToTenant() { + void shouldNotCreatePartnerReference_whenParticipantDoesNotBelongToTenant() { var infos1 = List.of(new DataspaceInfo(dataspace.getId(), List.of(), List.of(), Map.of())); var registration1 = new TenantRegistration("Tenant One", infos1); var tenant1 = tenantService.registerTenant(serviceProvider.getId(), registration1); From cd90cfdb38c82635a64fb1c586610434bb067a15 Mon Sep 17 00:00:00 2001 From: Enrico Peroglio <96304477+enryp@users.noreply.github.com> Date: Mon, 26 Jan 2026 10:00:03 +0100 Subject: [PATCH 7/8] Update src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java fix: test naming Co-authored-by: Tim Dahlmanns <13997715+timdah@users.noreply.github.com> --- .../redline/domain/service/TenantServiceIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java b/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java index 55bbc33..9a5f59c 100644 --- a/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java +++ b/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java @@ -686,7 +686,7 @@ void shouldNotCreatePartnerReference_whenParticipantDoesNotBelongToTenant() { } @Test - void shouldCreatePartnerReference_whenTenantDoesNotBelongToProvider() { + void shouldNotCreatePartnerReference_whenTenantDoesNotBelongToProvider() { // Create another service provider var otherProvider = new ServiceProvider(); otherProvider.setName("Other Provider"); From 5898ab1c8e7c46b941f0d3369a3f7c46cfbab41a Mon Sep 17 00:00:00 2001 From: Enrico Peroglio <96304477+enryp@users.noreply.github.com> Date: Mon, 26 Jan 2026 10:00:21 +0100 Subject: [PATCH 8/8] Update src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java fix: test naming Co-authored-by: Tim Dahlmanns <13997715+timdah@users.noreply.github.com> --- .../redline/domain/service/TenantServiceIntegrationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java b/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java index 9a5f59c..6152fbc 100644 --- a/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java +++ b/src/test/java/com/metaformsystems/redline/domain/service/TenantServiceIntegrationTest.java @@ -706,7 +706,7 @@ void shouldNotCreatePartnerReference_whenTenantDoesNotBelongToProvider() { } @Test - void shouldCreatePartnerReference_whenDataspaceInfoNotFound() { + void shouldNotCreatePartnerReference_whenDataspaceInfoNotFound() { final var tenant = new Tenant(); tenant.setName("Test Tenant"); tenant.setServiceProvider(serviceProvider);