diff --git a/src/main/java/com/metaformsystems/redline/api/controller/EdcDataController.java b/src/main/java/com/metaformsystems/redline/api/controller/EdcDataController.java index 36fa77e..2084ab3 100644 --- a/src/main/java/com/metaformsystems/redline/api/controller/EdcDataController.java +++ b/src/main/java/com/metaformsystems/redline/api/controller/EdcDataController.java @@ -81,13 +81,14 @@ public EdcDataController(DataAccessService dataAccessService, ObjectMapper objec public ResponseEntity uploadFile(@PathVariable Long participantId, @PathVariable Long tenantId, @PathVariable Long providerId, - @RequestPart("metadata") String metadata, + @RequestPart("publicMetadata") String publicMetadata, + @RequestPart("privateMetadata") String privateMetadata, @RequestPart("file") MultipartFile file) { try { - var metadataMap = objectMapper.readValue(metadata, new TypeReference>() { - }); - dataAccessService.uploadFileForParticipant(participantId, metadataMap, file.getInputStream(), file.getContentType(), file.getOriginalFilename()); + var publicMetadataMap = objectMapper.readValue(publicMetadata, new TypeReference>() {}); + var privateMetadataMap = objectMapper.readValue(privateMetadata, new TypeReference>() {}); + dataAccessService.uploadFileForParticipant(participantId, publicMetadataMap, privateMetadataMap, file.getInputStream(), file.getContentType(), file.getOriginalFilename()); } catch (IOException e) { return ResponseEntity.internalServerError().build(); } @@ -123,7 +124,6 @@ public ResponseEntity> listFiles(@PathVariable Long participa @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 = "counterPartyIdentifier", description = "Identifier of the counter-party to request catalog from", required = true) public ResponseEntity requestCatalog(@RequestHeader(name = "Cache-Control", required = false, defaultValue = "no-cache") String cacheControl, @PathVariable Long providerId, @PathVariable Long tenantId, @@ -172,6 +172,7 @@ public ResponseEntity> listContracts(@PathVariable Long providerI .type(cn.getType()); if (cn.getContractAgreement() != null) { + builder.id(cn.getContractAgreement().getId()); builder.agreementId(cn.getContractAgreement().getAgreementId()); builder.assetId(cn.getContractAgreement().getAssetId()); builder.signingDate(Instant.ofEpochSecond(cn.getContractAgreement().getContractSigningDate())); @@ -195,7 +196,7 @@ public ResponseEntity> listContracts(@PathVariable Long providerI @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) - @PostMapping("service-providers/{providerId}/tenants/{tenantId}/participants/{participantId}/contracts") + @PostMapping(value = "service-providers/{providerId}/tenants/{tenantId}/participants/{participantId}/contracts", produces = "text/plain") public ResponseEntity requestContract(@PathVariable Long providerId, @PathVariable Long tenantId, @PathVariable Long participantId, diff --git a/src/main/java/com/metaformsystems/redline/api/dto/response/Contract.java b/src/main/java/com/metaformsystems/redline/api/dto/response/Contract.java index 3064a09..8f548d8 100644 --- a/src/main/java/com/metaformsystems/redline/api/dto/response/Contract.java +++ b/src/main/java/com/metaformsystems/redline/api/dto/response/Contract.java @@ -19,6 +19,8 @@ public class Contract { private boolean isPending = true; + + private String id; private String counterParty; private String type; private String agreementId; @@ -37,6 +39,14 @@ public void setPending(boolean pending) { isPending = pending; } + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + public String getCounterParty() { return counterParty; } @@ -122,6 +132,11 @@ public Builder type(String type) { return this; } + public Builder id(String id) { + contract.setId(id); + return this; + } + public Builder agreementId(String agreementId) { contract.setAgreementId(agreementId); return this; 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 a42e9d3..a007929 100644 --- a/src/main/java/com/metaformsystems/redline/domain/service/DataAccessService.java +++ b/src/main/java/com/metaformsystems/redline/domain/service/DataAccessService.java @@ -45,6 +45,8 @@ import java.util.Set; import java.util.UUID; import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static com.metaformsystems.redline.domain.service.Constants.ASSET_PERMISSION; import static com.metaformsystems.redline.domain.service.Constants.MEMBERSHIP_CONTRACT_DEFINITION; @@ -70,21 +72,23 @@ public DataAccessService(DataPlaneApiClient dataPlaneApiClient, WebDidResolver w } @Transactional - public void uploadFileForParticipant(Long participantId, Map metadata, InputStream fileStream, String contentType, String originalFilename) { + public void uploadFileForParticipant(Long participantId, Map publicMetadata, Map privateMetadata, InputStream fileStream, String contentType, String originalFilename) { var participant = participantRepository.findById(participantId).orElseThrow(() -> new ObjectNotFoundException("Participant not found with id: " + participantId)); var participantContextId = participant.getParticipantContextId(); //0. upload file to data plane var assetId = UUID.randomUUID().toString(); - metadata.put("assetId", assetId); - var response = dataPlaneApiClient.uploadMultipart(participantContextId, metadata, fileStream); + publicMetadata.put("assetId", assetId); + var combinedMetadata = Stream.of(publicMetadata, privateMetadata).flatMap(m -> m.entrySet().stream()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + var response = dataPlaneApiClient.uploadMultipart(participantContextId, combinedMetadata, fileStream); var fileId = response.id(); //1. create asset - metadata.put("fileId", fileId); + publicMetadata.put("fileId", fileId); - var asset = createAsset(assetId, metadata, contentType, originalFilename); + var asset = createAsset(assetId, publicMetadata, privateMetadata, contentType, originalFilename); managementApiClient.createAsset(participantContextId, asset); // create CEL expression @@ -114,7 +118,7 @@ public void uploadFileForParticipant(Long participantId, Map met //2. track uploaded file in DB - participant.getUploadedFiles().add(new UploadedFile(fileId, originalFilename, contentType, metadata)); + participant.getUploadedFiles().add(new UploadedFile(fileId, originalFilename, contentType, publicMetadata)); } @Transactional @@ -261,13 +265,15 @@ private ContractNegotiation getAgreement(String participantContextId, ContractNe return negotiation; } - private Asset createAsset(String id, Map metadata, String contentType, String originalFilename) { + private Asset createAsset(String id, Map publicMetadata, Map privateMetadata, String contentType, String originalFilename) { var properties = new HashMap(Map.of( "description", "A file uploaded by Redline on " + Instant.now().toString(), "contentType", contentType, "originalFilename", originalFilename)); - properties.putAll(metadata); + properties.putAll(publicMetadata); + + privateMetadata.put("permission", ASSET_PERMISSION); return Asset.Builder.aNewAsset() .id(id) @@ -275,8 +281,8 @@ private Asset createAsset(String id, Map metadata, String conten "type", "HttpCertData", "@type", "DataAddress" )) - .privateProperties(Map.of("permission", ASSET_PERMISSION)) //this is targeted by the CEL expression, so it must be a private property - .properties(properties) + .privateProperties(privateMetadata) //this is targeted by the CEL expression, so it must be a private property + .properties(Map.of("properties", properties)) .build(); } diff --git a/src/main/java/com/metaformsystems/redline/infrastructure/client/management/dto/Dataset.java b/src/main/java/com/metaformsystems/redline/infrastructure/client/management/dto/Dataset.java index 41f54ef..4064750 100644 --- a/src/main/java/com/metaformsystems/redline/infrastructure/client/management/dto/Dataset.java +++ b/src/main/java/com/metaformsystems/redline/infrastructure/client/management/dto/Dataset.java @@ -33,10 +33,7 @@ public class Dataset { @JsonProperty("distribution") private List distribution; - @JsonProperty("description") - private String description; - - @JsonProperty("properties") + @JsonProperty("edc:properties") private Map properties = new HashMap<>(); public String getId() { @@ -71,14 +68,6 @@ public void setDistribution(List distribution) { this.distribution = distribution; } - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - public Map getProperties() { return properties; } diff --git a/src/test/java/com/metaformsystems/redline/TransferEndToEndTest.java b/src/test/java/com/metaformsystems/redline/TransferEndToEndTest.java index 43bec02..714a345 100644 --- a/src/test/java/com/metaformsystems/redline/TransferEndToEndTest.java +++ b/src/test/java/com/metaformsystems/redline/TransferEndToEndTest.java @@ -83,7 +83,8 @@ void testTransferFile() throws Exception { baseRequest() .contentType(ContentType.MULTIPART) .multiPart("file", "testfile.txt", "This is a test file.".getBytes()) - .multiPart("metadata", "{\"slug\": \"%s\"}".formatted(slug), "application/json") + .multiPart("publicMetadata", "{\"slug\": \"%s\"}".formatted(slug), "application/json") + .multiPart("privateMetadata", "{\"privateSlug\": \"%s\"}".formatted(slug), "application/json") .post("/api/ui/service-providers/%s/tenants/%s/participants/%s/files".formatted(SERVICE_PROVIDER_ID, provider.tenantId(), provider.participantId())) .then() .statusCode(200); diff --git a/src/test/java/com/metaformsystems/redline/api/controller/EdcDataControllerTest.java b/src/test/java/com/metaformsystems/redline/api/controller/EdcDataControllerTest.java index 84e96c6..89bfdb8 100644 --- a/src/test/java/com/metaformsystems/redline/api/controller/EdcDataControllerTest.java +++ b/src/test/java/com/metaformsystems/redline/api/controller/EdcDataControllerTest.java @@ -164,8 +164,10 @@ void shouldUploadFile() throws Exception { ); // Create metadata - var metadataPart = new MockPart("metadata", "{\"foo\": \"bar\"}".getBytes()); - metadataPart.getHeaders().setContentType(MediaType.APPLICATION_JSON); + var publicMetadata = new MockPart("publicMetadata", "{\"foo\": \"bar\"}".getBytes()); + publicMetadata.getHeaders().setContentType(MediaType.APPLICATION_JSON); + var privateMetadata = new MockPart("privateMetadata", "{\"private\": \"value\"}".getBytes()); + privateMetadata.getHeaders().setContentType(MediaType.APPLICATION_JSON); // Mock the upload response from the dataplane mockWebServer.enqueue(new MockResponse() @@ -189,7 +191,7 @@ void shouldUploadFile() throws Exception { mockMvc.perform(multipart("/api/ui/service-providers/{providerId}/tenants/{tenantId}/participants/{participantId}/files", serviceProvider.getId(), tenant.getId(), participant.getId()) .file(mockFile) - .part(metadataPart)) + .part(publicMetadata, privateMetadata)) .andExpect(status().isOk()); assertThat(participantRepository.findById(participant.getId())).isPresent()