From 1f157d3862d8548ada0784aa0b3dfc26d7b94ab8 Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Mon, 20 Oct 2025 16:11:22 +0200 Subject: [PATCH 01/51] Feature: Added update schema only on changes - Added isSameSchema function, allowing RDF models to be compared. - Added GetAllSchemas function, fetching all current schemas in the FDP. - Added SchemaToolsTest.java, testing this new feature. - Improved readability in SchemaTools.java by splitting up functons inside run. --- pom.xml | 9 +- .../nl/healthri/fdp/uploadschema/FDP.java | 55 ++++- .../fdp/uploadschema/SchemaTools.java | 145 +++++++---- .../tasks/ShapeUpdateInsertTask.java | 19 +- .../fdp/uploadschema/utils/RdfUtils.java | 2 - .../uploadschema/utils/SchemaToolsTest.java | 225 ++++++++++++++++++ 6 files changed, 402 insertions(+), 53 deletions(-) create mode 100644 src/test/java/nl/healthri/fdp/uploadschema/utils/SchemaToolsTest.java diff --git a/pom.xml b/pom.xml index bb9bc08..a0fde61 100644 --- a/pom.xml +++ b/pom.xml @@ -117,8 +117,6 @@ fr.sparna.rdf.xls2rdf xls2rdf-pom 3.2.1 - - org.apache.poi @@ -135,6 +133,13 @@ poi-ooxml-schemas 4.1.0 + + + org.mockito + mockito-core + 5.20.0 + test + diff --git a/src/main/java/nl/healthri/fdp/uploadschema/FDP.java b/src/main/java/nl/healthri/fdp/uploadschema/FDP.java index 7f148c0..954a48f 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/FDP.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/FDP.java @@ -1,6 +1,7 @@ package nl.healthri.fdp.uploadschema; import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import nl.healthri.fdp.uploadschema.requestbodies.*; import nl.healthri.fdp.uploadschema.requestresponses.*; @@ -9,12 +10,16 @@ import nl.healthri.fdp.uploadschema.utils.RequestBuilder; import nl.healthri.fdp.uploadschema.utils.ResourceMap; import nl.healthri.fdp.uploadschema.utils.ShapesMap; +import org.apache.http.HttpStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.helpers.MessageFormatter; +import java.io.IOException; import java.net.URI; import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.*; @@ -38,6 +43,8 @@ private FDP(URI url) { } public static FDP connectToFdp(URI url, String username, String password) { + logger.info("Connecting to FDP at {} as {} ", url, username); + FDP fdp = new FDP(url); var info = fdp.request().setUri(fdp.url("actuator/info")).get(FDPInfoResponse.class); logger.info("FDP info: {}", info.toString()); @@ -161,7 +168,7 @@ t.model, getParentUID(t.parents), t.shape, t.url()); - //result of request is not needed. + //result of request is not needed request().setUri(url + "/metadata-schemas/" + t.uuid + "/draft") .setBody(esp) .setToken(token) @@ -179,6 +186,52 @@ public void releaseSchema(ShapeUpdateInsertTask t) { .post(SchemaDataResponse.class); } + + public List GetAllSchemas(){ + logger.info("Getting all metadata schemas"); + try { + HttpClient client = HttpClient.newBuilder() + .build(); + + HttpRequest request = HttpRequest.newBuilder() + .GET() + .uri(new URI(url + "/metadata-schemas/")) + .header("accept", "application/json") + .header("Content-Type", "application/json") + .header("Authorization", String.valueOf(token)) + .build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Handle each response based on Fair Data Point (FDP) Swagger documentation. + switch (response.statusCode()) { + case 200 -> logger.info("OK"); + case 400 -> + throw new IllegalArgumentException(String.valueOf(HttpStatus.SC_BAD_REQUEST)); + case 401 -> + throw new SecurityException(String.valueOf(HttpStatus.SC_UNAUTHORIZED)); + case 403 -> + throw new SecurityException(String.valueOf(HttpStatus.SC_FORBIDDEN)); + case 404 -> + throw new IOException(String.valueOf(HttpStatus.SC_NOT_FOUND)); + case 500 -> + throw new IOException(String.valueOf(HttpStatus.SC_INTERNAL_SERVER_ERROR)); + default -> { + throw new RuntimeException("Unexpected HTTP status: " + response.statusCode()); + } + } + + ObjectMapper objectMapper = new ObjectMapper(); + TypeReference> schemaDataTypeReference = new TypeReference>(){}; + List schemaDataResponseList = objectMapper.readValue(response.body(), schemaDataTypeReference); + + return schemaDataResponseList; + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + @Override public void close() { if (client != null) { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index 7822524..c14da26 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -1,5 +1,6 @@ package nl.healthri.fdp.uploadschema; +import nl.healthri.fdp.uploadschema.requestresponses.SchemaDataResponse; import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; import nl.healthri.fdp.uploadschema.utils.Properties; @@ -16,6 +17,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import static java.util.function.Predicate.not; @@ -49,65 +53,114 @@ public static void main(String... args) { @Override public void run() { try { - final Properties p = Properties.load(propertyFile); - if (command == CommandEnum.TEMPLATE) { - //1 read all(!) excel files from folder, write shapes in Pieces directory - logger.info("reading templates from {} ", p.templateDir); - for (var e : XlsToRdfUtils.getTemplateFiles(p.templateDir).entrySet()) { - logger.info(" converting {} ", e.getValue()); - Path path = p.getPiecesDir().resolve(e.getKey() + ".ttl"); - String shacl = XlsToRdfUtils.createShacl(e.getValue()); - Files.write(path, shacl.getBytes()); + final Properties properties = Properties.load(propertyFile); + final FDP fdp = FDP.connectToFdp(hostname, username, password); + + switch (command){ + case TEMPLATE -> { + convertTemplatesToShaclShapes(properties); + mergeShapesToFdpSchemas(properties); + mergeShapesForValidation(properties); } - //2 merge piece to FairDataPoint dir. - logger.info("Writing files: {}", p.getFiles().keySet()); - for (var e : p.getFiles(p.getPiecesDir()).entrySet()) { - Path path = p.getFairDataPointDir().resolve(RdfUtils.schemaToFile(e.getKey())); - Model m = RdfUtils.readFiles(e.getValue()); - RdfUtils.safeModel(path, m); + case BOTH -> { + createOrUpdateSchemas(fdp, properties); + addResourceDescriptions(fdp, properties); } - //3 merge all pieces into validation dir. + case SCHEMA -> + createOrUpdateSchemas(fdp, properties); + case RESOURCE -> + addResourceDescriptions(fdp, properties); + } + } catch (IOException io) { + throw new RuntimeException(io); + } + } - Path path = p.getValidationDir().resolve("HRI-Datamodel-shapes.ttl"); - logger.info("Write validation file {} combining {} files", path, p.getAllFiles().size()); - Model m = RdfUtils.readFiles(new ArrayList<>(p.getAllFiles())); - RdfUtils.safeModel(path, m); - } else { - logger.info("Connecting to FDP at {} as {} ", hostname, username); + public void convertTemplatesToShaclShapes(Properties properties) throws IOException { + logger.info("reading templates from {} ", properties.templateDir); - final FDP fdp = FDP.connectToFdp(hostname, username, password); + for (var e : XlsToRdfUtils.getTemplateFiles(properties.templateDir).entrySet()) { + logger.info(" converting {} ", e.getValue()); + Path path = properties.getPiecesDir().resolve(e.getKey() + ".ttl"); + String shacl = XlsToRdfUtils.createShacl(e.getValue()); + Files.write(path, shacl.getBytes()); + } + } - if (command == CommandEnum.SCHEMA || command == CommandEnum.BOTH) { - //Shapes we want to update/insert - var shapeTasks = ShapeUpdateInsertTask.createTasks(p, fdp); + public void mergeShapesToFdpSchemas(Properties properties) throws IOException { + logger.info("Writing files: {}", properties.getFiles().keySet()); -// insert new schemas and keep the UUID, this is needed for the "release step" - shapeTasks.stream().filter(ShapeUpdateInsertTask::isInsert).forEach(fdp::insertSchema); + for (var e : properties.getFiles(properties.getPiecesDir()).entrySet()) { + Path path = properties.getFairDataPointDir().resolve(RdfUtils.schemaToFile(e.getKey())); + Model m = RdfUtils.readFiles(e.getValue()); + RdfUtils.safeModel(path, m); + } + } -// update existing shape, will get status draft. - shapeTasks.stream().filter(not(ShapeUpdateInsertTask::isInsert)).forEach(fdp::updateSchema); + public void mergeShapesForValidation(Properties properties) throws IOException { + logger.info("Merging files: {}", properties.getValidationDir()); - //the draft-schema are released, - shapeTasks.forEach(fdp::releaseSchema); - } + Path path = properties.getValidationDir().resolve("HRI-Datamodel-shapes.ttl"); + logger.info("Write validation file {} combining {} files", path, properties.getAllFiles().size()); + Model m = RdfUtils.readFiles(new ArrayList<>(properties.getAllFiles())); + RdfUtils.safeModel(path, m); + } - if (command == CommandEnum.RESOURCE || command == CommandEnum.BOTH) { - //add resource-descriptions - var resourceTasks = ResourceUpdateInsertTask.createTask(p, fdp); - resourceTasks.stream().filter(ResourceUpdateInsertTask::isInsert).forEach(fdp::insertResource); + public void createOrUpdateSchemas(FDP fdp, Properties properties) throws IOException { + logger.info("Creating/updating schemas from tasks to FDP"); - if (resourceTasks.stream().noneMatch(not(ResourceUpdateInsertTask::isInsert))) { - logger.warn("Updating resources is not supported yet, but will try to add children if needed)"); - } + var shapeTasks = ShapeUpdateInsertTask.createTasks(properties, fdp); + List schemasToUpdate = filterSchemasToUpdate(fdp, shapeTasks); - //add the previous resources as child to parent. - var resourceTasksParents = ResourceUpdateInsertTask.createParentTask(p, fdp); - resourceTasksParents.stream().filter(ResourceUpdateInsertTask::hasChild).forEach(fdp::updateResource); - } + schemasToUpdate.forEach(task -> { + if (task.isInsert()) { + fdp.insertSchema(task); + } else { + fdp.updateSchema(task); + } + + fdp.releaseSchema(task); + }); + } + + public void addResourceDescriptions(FDP fdp, Properties properties){ + logger.info("Adding resource descriptions from resource tasks to FDP"); + + var resourceTasks = ResourceUpdateInsertTask.createTask(properties, fdp); + resourceTasks.stream().filter(ResourceUpdateInsertTask::isInsert).forEach(fdp::insertResource); + + if (resourceTasks.stream().noneMatch(not(ResourceUpdateInsertTask::isInsert))) { + logger.warn("Updating resources is not supported yet, but will try to add children if needed)"); + } + + //add the previous resources as child to parent. + var resourceTasksParents = ResourceUpdateInsertTask.createParentTask(properties, fdp); + resourceTasksParents.stream().filter(ResourceUpdateInsertTask::hasChild).forEach(fdp::updateResource); + } + + public List filterSchemasToUpdate(FDP fdp, List shapeUpdateInsertTaskList) throws IOException { + logger.info("Getting all schemas with schema changes"); + + // Maps all schemas found with schema name as key for easy lookup. + Map existingSchemaMap = fdp.GetAllSchemas().stream() + .collect(Collectors.toMap( + SchemaDataResponse::name, + schema -> schema + )); + + List schemasToUpdate = new ArrayList<>(); + for (ShapeUpdateInsertTask task : shapeUpdateInsertTaskList) { + SchemaDataResponse existingSchema = existingSchemaMap.get(task.shape); + if (existingSchema == null) { + continue; + } + + if (!task.isSameSchema(existingSchema)){ + schemasToUpdate.add(task); } - } catch (IOException io) { - throw new RuntimeException(io); } + + return schemasToUpdate; } public enum CommandEnum { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java index 653a136..3ab5288 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java @@ -2,11 +2,18 @@ import nl.healthri.fdp.uploadschema.FDP; import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.requestresponses.SchemaDataResponse; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.RdfUtils; +import org.eclipse.rdf4j.model.Model; +import org.eclipse.rdf4j.model.util.Models; +import org.eclipse.rdf4j.rio.RDFFormat; +import org.eclipse.rdf4j.rio.Rio; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.io.StringReader; import java.net.URI; import java.util.List; import java.util.NoSuchElementException; @@ -20,8 +27,7 @@ public class ShapeUpdateInsertTask { public final String shape; public Version version; public String uuid; - //name of parents for this schema. - public Set parents; + public Set parents; //name of parents for this schema. public String model; public boolean exists = false; @@ -69,4 +75,13 @@ public String url() { public boolean isInsert() { return !exists; } + + public boolean isSameSchema(SchemaDataResponse schemaData) throws IOException { + // Parse TTL strings into RDF4J Models + Model taskModel = Rio.parse(new StringReader(this.model), "", RDFFormat.TURTLE); + Model schemaResponseModel = Rio.parse(new StringReader(schemaData.latest().definition()), "", RDFFormat.TURTLE); + + // Check if models have equivalent RDF Graphs to know if schema should be updated + return Models.isomorphic(taskModel, schemaResponseModel); + } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java index 8027022..7c1d904 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java @@ -82,7 +82,6 @@ public static Model readFiles(List files) { } } - @SuppressWarnings("unused") public static void printModelAsTurtle(Model m) { saveModelToStream(System.out, m); } @@ -93,7 +92,6 @@ public static String modelAsTurtleString(Model m) { return out.toString(); } - @SuppressWarnings("unused") public static void safeModel(Path p, Model m) throws IOException { saveModelToStream(Files.newOutputStream(p), m); } diff --git a/src/test/java/nl/healthri/fdp/uploadschema/utils/SchemaToolsTest.java b/src/test/java/nl/healthri/fdp/uploadschema/utils/SchemaToolsTest.java new file mode 100644 index 0000000..05e1474 --- /dev/null +++ b/src/test/java/nl/healthri/fdp/uploadschema/utils/SchemaToolsTest.java @@ -0,0 +1,225 @@ +package nl.healthri.fdp.uploadschema.utils; + +import nl.healthri.fdp.uploadschema.FDP; +import nl.healthri.fdp.uploadschema.SchemaTools; +import nl.healthri.fdp.uploadschema.requestresponses.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.*; + +public class SchemaToolsTest { + + private SchemaTools schemaTools; + @Mock + private FDP mockFdp; + + // Initialize Mockito mocks before each test + @BeforeEach + void setUp() { + // Must initialize mocks defined with @Mock + MockitoAnnotations.openMocks(this); + schemaTools = new SchemaTools(); + } + + private ShapeUpdateInsertTask createMockTask(String shapeName, boolean isInsert, boolean isSameSchemaResult) throws IOException { + ShapeUpdateInsertTask realTask = new ShapeUpdateInsertTask(shapeName); + ShapeUpdateInsertTask spyTask = spy(realTask); + doReturn(isInsert).when(spyTask).isInsert(); + + if (!isInsert) { + doReturn(isSameSchemaResult).when(spyTask).isSameSchema(any(SchemaDataResponse.class)); + } + + return spyTask; + } + + // Creates a SchemaDataResponse. + private SchemaDataResponse createSchemaResponse(String name) { + SchemaDataResponse mockSchemaDataResponse = mock(SchemaDataResponse.class); + + doReturn(name).when(mockSchemaDataResponse).name(); + return mockSchemaDataResponse; + } + + /** + * Condition: Existing schema map is empty. + * Expected: No updates, as any non-insert task won't find an existing schema. + */ + @Test + void filterSchemasToUpdate_NoExistingSchemas_ReturnsEmptyList() throws IOException { + // Arrange + when(mockFdp.GetAllSchemas()).thenReturn(Collections.emptyList()); + + ShapeUpdateInsertTask taskA = createMockTask("SchemaA", false, false); + List inputTasks = Collections.singletonList(taskA); + + // Act + List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); + + // Assert + assertTrue(result.isEmpty(), "Tasks should be filtered out when no existing schemas are found."); + verify(taskA, never()).isSameSchema(any()); + } + + + /** + * Condition: The input list of tasks is empty. + * Expected: Empty result list. + */ + @Test + void filterSchemasToUpdate_EmptyInputTaskList_ReturnsEmptyList() throws IOException { + // Arrange + List existingSchemas = Collections.singletonList(createSchemaResponse("SchemaA")); + when(mockFdp.GetAllSchemas()).thenReturn(existingSchemas); + List inputTasks = new ArrayList<>(); + + // Act + List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); + + // Assert + assertTrue(result.isEmpty(), "Result should be empty when the input task list is empty."); + } + + /** + * Condition: A task's 'isInsert()' method returns true. + * Expected: Insert tasks must be filtered out (ignored). + */ + @Test + void filterSchemasToUpdate_TaskIsInsert_TaskIsFilteredOut() throws IOException { + // Arrange + List existingSchemas = Collections.singletonList(createSchemaResponse("SchemaA")); + when(mockFdp.GetAllSchemas()).thenReturn(existingSchemas); + + ShapeUpdateInsertTask insertTask = createMockTask("SchemaA", true, false); + List inputTasks = Collections.singletonList(insertTask); + + // Act + List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); + + // Assert + assertTrue(result.isEmpty(), "Insert task should be filtered out."); + verify(insertTask, times(1)).isSameSchema(any()); + } + + /** + * Condition: Task is an update, but its shape name is not found in the existing map. + * Expected: Task must be filtered out. + */ + @Test + void filterSchemasToUpdate_ExistingSchemaNotFound_TaskIsFilteredOut() throws IOException { + // Arrange + List existingSchemas = Collections.singletonList(createSchemaResponse("SchemaA")); + when(mockFdp.GetAllSchemas()).thenReturn(existingSchemas); + + // Task is for SchemaB (update, but not found) + ShapeUpdateInsertTask nonExistingTask = createMockTask("SchemaB", false, false); + List inputTasks = Collections.singletonList(nonExistingTask); + + // Act + List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); + + // Assert + assertTrue(result.isEmpty(), "Task targeting a non-existing schema should be filtered out."); + verify(nonExistingTask, never()).isSameSchema(any()); + } + + /** + * Condition: Task is an update, schema exists, and 'isSameSchema' returns false. + * Expected: Task should be included in the result. + */ + @Test + void filterSchemasToUpdate_ExistingSchemaIsDifferent_TaskIsIncluded() throws IOException { + // Arrange + SchemaDataResponse existingSchemaA = createSchemaResponse("SchemaA"); + when(mockFdp.GetAllSchemas()).thenReturn(Collections.singletonList(existingSchemaA)); + + // Task reports *not* being the same schema (false means different/needs update) + ShapeUpdateInsertTask differentTaskA = createMockTask("SchemaA", false, false); + List inputTasks = Collections.singletonList(differentTaskA); + + // Act + List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); + + // Assert + assertEquals(1, result.size(), "Task for a different schema should be included."); + assertEquals(differentTaskA, result.getFirst()); + verify(differentTaskA, times(1)).isSameSchema(existingSchemaA); + } + + /** + * Condition: Task is an update, schema exists, and 'isSameSchema' returns true. + * Expected: Task should be filtered out (no update needed). + */ + @Test + void filterSchemasToUpdate_ExistingSchemaIsSame_TaskIsFilteredOut() throws IOException { + // Arrange + SchemaDataResponse existingSchemaA = createSchemaResponse("SchemaA"); + when(mockFdp.GetAllSchemas()).thenReturn(Collections.singletonList(existingSchemaA)); + + // Task reports being the same schema (true means no change) + ShapeUpdateInsertTask sameTaskA = createMockTask("SchemaA", false, true); + List inputTasks = Collections.singletonList(sameTaskA); + + // Act + List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); + + // Assert + assertTrue(result.isEmpty(), "Task for a schema with the same content should be filtered out."); + verify(sameTaskA, times(1)).isSameSchema(existingSchemaA); + } + + /** + * Condition: Input list contains inserts, non-existent targets, same-content updates, and different-content updates. + * Expected: Only the tasks requiring updates should be returned. + */ + @Test + void filterSchemasToUpdate_MixedTasks_ReturnsOnlyNecessaryUpdates() throws IOException { + // Arrange + SchemaDataResponse existingA = createSchemaResponse("SchemaA"); + SchemaDataResponse existingB = createSchemaResponse("SchemaB"); + SchemaDataResponse existingC = createSchemaResponse("SchemaC"); + + List existingSchemas = Arrays.asList(existingA, existingB, existingC); + when(mockFdp.GetAllSchemas()).thenReturn(existingSchemas); + + ShapeUpdateInsertTask insertTask = createMockTask("SchemaD", true, false); // 1. Filtered out (Insert) + ShapeUpdateInsertTask nonExistingTask = createMockTask("SchemaE", false, false); // 2. Filtered out (Non-existing target) + ShapeUpdateInsertTask sameTask = createMockTask("SchemaA", false, true); // 3. Filtered out (Same content) + ShapeUpdateInsertTask differentTask1 = createMockTask("SchemaB", false, false); // 4. Included (Different content) + ShapeUpdateInsertTask differentTask2 = createMockTask("SchemaC", false, false); // 5. Included (Different content) + + List inputTasks = Arrays.asList( + insertTask, + nonExistingTask, + sameTask, + differentTask1, + differentTask2 + ); + + // Act + List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); + + // Assert + assertEquals(2, result.size(), "Only two tasks (B and C) should be included."); + assertTrue(result.contains(differentTask1)); + assertTrue(result.contains(differentTask2)); + + verify(insertTask, times(0)).isSameSchema(existingB); + verify(nonExistingTask, times(0)).isSameSchema(existingC); + verify(sameTask, times(1)).isSameSchema(existingA); + verify(differentTask1, times(1)).isSameSchema(existingB); + verify(differentTask2, times(1)).isSameSchema(existingC); + } +} \ No newline at end of file From fcc3116a43b33c75a72782fdcf205450bff6732e Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Mon, 20 Oct 2025 16:35:24 +0200 Subject: [PATCH 02/51] Fix: fixed filterSchemasToUpdate_TaskIsInsert_TastIsFiltered test --- .../tasks/ShapeUpdateInsertTask.java | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java index 3ab5288..2df5aa5 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java @@ -77,9 +77,23 @@ public boolean isInsert() { } public boolean isSameSchema(SchemaDataResponse schemaData) throws IOException { + StringReader stringReaderNew; + if(this.model == null){ + stringReaderNew = new StringReader(""); + } else { + stringReaderNew = new StringReader(this.model); + } + + StringReader stringReaderOld; + if(schemaData.latest() == null){ + stringReaderOld = new StringReader(""); + } else { + stringReaderOld = new StringReader(schemaData.latest().definition()); + } + // Parse TTL strings into RDF4J Models - Model taskModel = Rio.parse(new StringReader(this.model), "", RDFFormat.TURTLE); - Model schemaResponseModel = Rio.parse(new StringReader(schemaData.latest().definition()), "", RDFFormat.TURTLE); + Model taskModel = Rio.parse(stringReaderNew, "", RDFFormat.TURTLE); + Model schemaResponseModel = Rio.parse(stringReaderOld, "", RDFFormat.TURTLE); // Check if models have equivalent RDF Graphs to know if schema should be updated return Models.isomorphic(taskModel, schemaResponseModel); From cd4a9ad4d77fdc774bf207e95eeb1cdd89a0e68c Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Wed, 22 Oct 2025 11:38:34 +0200 Subject: [PATCH 03/51] Feat: Added improved error handling for reading and mapping of Properties.yaml --- .../tasks/ShapeUpdateInsertTask.java | 1 + .../fdp/uploadschema/utils/Properties.java | 28 +++++++++++++------ .../fdp/uploadschema/utils/RdfUtils.java | 7 +++-- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java index 2df5aa5..8bc63ab 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java @@ -51,6 +51,7 @@ public static List createTasks(Properties p, FDP fdp) { ShapeUpdateInsertTask.model = RdfUtils.modelAsTurtleString(RdfUtils.readFiles(ttlFiles)); if (shapesOnFdp.isPresent(r)) { + // todo: add current compare ttl schemas here ShapeUpdateInsertTask.version = shapesOnFdp.getVersion(r).get().next(requestedVersion); //next patch version ShapeUpdateInsertTask.uuid = shapesOnFdp.getUUID(r).get(); ShapeUpdateInsertTask.exists = true; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java index 921f5a8..214688f 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java @@ -1,12 +1,14 @@ package nl.healthri.fdp.uploadschema.utils; import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.exc.StreamReadException; +import com.fasterxml.jackson.databind.DatabindException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import nl.healthri.fdp.uploadschema.Version; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -22,16 +24,11 @@ public class Properties { public final Map resources = new HashMap<>(); public List schemasToPublish; public String schemaVersion; - public String inputDir; - public String templateDir; public String outputRoot; - @JsonProperty("piecesDir") public String piecesDir; - @JsonProperty("fairDataPointDir") public String fairDataPointDir; - @JsonProperty("validationDir") public String validationDir; public record ResourceProperties( @@ -41,8 +38,23 @@ public record ResourceProperties( } public static Properties load(File file) throws IOException { - var mapper = new ObjectMapper(new YAMLFactory()); - return mapper.readValue(file, Properties.class); + if (!file.exists() || !file.isFile()) { + throw new FileNotFoundException("Properties file not found: " + file.getAbsolutePath()); + } + + try { + var mapper = new ObjectMapper(new YAMLFactory()); + return mapper.readValue(file, Properties.class); + } catch (StreamReadException e) { + // Malformed YAML (e.g., bad indentation, syntax error) + throw new IOException("Failed to read the YAML contents from file: " + file.getAbsolutePath(), e); + } catch (DatabindException e) { + // Valid YAML, but doesn't mattch the Properties structure + throw new IOException("Failed to bind YAML content to Properties object from file: " + file.getAbsolutePath(), e); + } catch (IOException e) { + // Other IO issues + throw new IOException("Error while reading properties from file: " + file.getAbsolutePath(), e); + } } /** diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java index 7c1d904..fe68a53 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java @@ -34,6 +34,8 @@ private RdfUtils() { } private static void validateNamespaces(Model model) { + logger.info("validating namespaces {}", model.getNamespaces()); + // Collect all namespaces used in the model final Set usedNamespaces = model.stream() .flatMap(st -> Set.of(st.getSubject(), st.getPredicate(), st.getObject()).stream()) @@ -57,7 +59,7 @@ private static void validateNamespaces(Model model) { } private static void readFile(URI uri, RDFParser parser) throws IOException { - logger.debug("reading {}", uri.getPath()); + logger.info("reading {}", uri.getPath()); try { InputStream fis = getInputStream(uri); parser.parse(fis); @@ -67,8 +69,9 @@ private static void readFile(URI uri, RDFParser parser) throws IOException { } public static Model readFiles(List files) { + logger.info("reading shacls from {}", files.getFirst().toString()); + try { - logger.info("reading shacls from {}", files.getFirst().toString()); RDFParser rdfParser = Rio.createParser(RDFFormat.TURTLE); Model model = new LinkedHashModel(); rdfParser.setRDFHandler(new StatementCollector(model)); From a7dbf61f307fe5177329f535f4711dfcaec30eb3 Mon Sep 17 00:00:00 2001 From: PatrickDekkerHealthRI <168626347+PatrickDekkerHealthRI@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:51:11 +0200 Subject: [PATCH 04/51] feat: compare schema before update and improve testability of code --- .../fdp/uploadschema/SchemaTools.java | 100 ++++---- .../tasks/ShapeUpdateInsertTask.java | 54 ++--- .../fdp/uploadschema/utils/FileHandler.java | 123 ++++++++++ .../fdp/uploadschema/utils/RdfUtils.java | 126 +---------- .../fdp/uploadschema/utils/ShapesMap.java | 8 +- .../tasks/ShapeUpdateInsertTaskTest.java | 214 ++++++++++++++++++ 6 files changed, 413 insertions(+), 212 deletions(-) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java create mode 100644 src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index c14da26..6841f50 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -1,8 +1,8 @@ package nl.healthri.fdp.uploadschema; -import nl.healthri.fdp.uploadschema.requestresponses.SchemaDataResponse; import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; +import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.RdfUtils; import org.eclipse.rdf4j.model.Model; @@ -17,9 +17,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; import static java.util.function.Predicate.not; @@ -45,6 +42,9 @@ public class SchemaTools implements Runnable { @CommandLine.Option(names = {"-c", "--command"}, defaultValue = "both", description = "Valid values: ${COMPLETION-CANDIDATES} (default: ${DEFAULT-VALUE})", converter = CommandEnumConverter.class) CommandEnum command; + @CommandLine.Option(names = {"-f", "--force"}, defaultValue = "false", description = "Force upload even if schema has not changed") + boolean force; + public static void main(String... args) { var cmd = new CommandLine(new SchemaTools()); System.exit(cmd.execute(args)); @@ -55,21 +55,20 @@ public void run() { try { final Properties properties = Properties.load(propertyFile); final FDP fdp = FDP.connectToFdp(hostname, username, password); + final FileHandler fileHandler = new FileHandler(); - switch (command){ + switch (command) { case TEMPLATE -> { - convertTemplatesToShaclShapes(properties); - mergeShapesToFdpSchemas(properties); - mergeShapesForValidation(properties); + convertTemplatesToShaclShapes(properties); + mergeShapesToFdpSchemas(properties, fileHandler); + mergeShapesForValidation(properties, fileHandler); } case BOTH -> { - createOrUpdateSchemas(fdp, properties); - addResourceDescriptions(fdp, properties); + createOrUpdateSchemas(fdp, properties, force, fileHandler); + addResourceDescriptions(fdp, properties); } - case SCHEMA -> - createOrUpdateSchemas(fdp, properties); - case RESOURCE -> - addResourceDescriptions(fdp, properties); + case SCHEMA -> createOrUpdateSchemas(fdp, properties, force, fileHandler); + case RESOURCE -> addResourceDescriptions(fdp, properties); } } catch (IOException io) { throw new RuntimeException(io); @@ -87,43 +86,53 @@ public void convertTemplatesToShaclShapes(Properties properties) throws IOExcept } } - public void mergeShapesToFdpSchemas(Properties properties) throws IOException { + public void mergeShapesToFdpSchemas(Properties properties, FileHandler rdfUtils) throws IOException { logger.info("Writing files: {}", properties.getFiles().keySet()); for (var e : properties.getFiles(properties.getPiecesDir()).entrySet()) { - Path path = properties.getFairDataPointDir().resolve(RdfUtils.schemaToFile(e.getKey())); - Model m = RdfUtils.readFiles(e.getValue()); - RdfUtils.safeModel(path, m); + Path path = properties.getFairDataPointDir().resolve(RdfUtils.schemaToFilename(e.getKey())); + Model m = rdfUtils.readFiles(e.getValue()); + rdfUtils.safeModel(path, m); } } - public void mergeShapesForValidation(Properties properties) throws IOException { + public void mergeShapesForValidation(Properties properties, FileHandler rdfUtils) throws IOException { logger.info("Merging files: {}", properties.getValidationDir()); Path path = properties.getValidationDir().resolve("HRI-Datamodel-shapes.ttl"); logger.info("Write validation file {} combining {} files", path, properties.getAllFiles().size()); - Model m = RdfUtils.readFiles(new ArrayList<>(properties.getAllFiles())); - RdfUtils.safeModel(path, m); + Model m = rdfUtils.readFiles(new ArrayList<>(properties.getAllFiles())); + rdfUtils.safeModel(path, m); } - public void createOrUpdateSchemas(FDP fdp, Properties properties) throws IOException { + public void createOrUpdateSchemas(FDP fdp, Properties properties, boolean force, FileHandler fileHandler) throws IOException { logger.info("Creating/updating schemas from tasks to FDP"); - var shapeTasks = ShapeUpdateInsertTask.createTasks(properties, fdp); - List schemasToUpdate = filterSchemasToUpdate(fdp, shapeTasks); - - schemasToUpdate.forEach(task -> { - if (task.isInsert()) { - fdp.insertSchema(task); - } else { - fdp.updateSchema(task); + var shapeTasks = ShapeUpdateInsertTask.createTasks(properties, fdp, fileHandler); + shapeTasks.forEach(task -> { + switch (task.status()) { + case INSERT -> { + fdp.insertSchema(task); + fdp.releaseSchema(task); + } + case SAME -> { + if (force) { + fdp.updateSchema(task); + fdp.releaseSchema(task); + logger.info("Schema {} is updated, it was the same but force was set", task.shape); + } else { + logger.warn("Schema {} is not updated because it's still the same", task.shape); + } + } + case UPDATE -> { + fdp.updateSchema(task); + fdp.releaseSchema(task); + } } - - fdp.releaseSchema(task); }); } - public void addResourceDescriptions(FDP fdp, Properties properties){ + public void addResourceDescriptions(FDP fdp, Properties properties) { logger.info("Adding resource descriptions from resource tasks to FDP"); var resourceTasks = ResourceUpdateInsertTask.createTask(properties, fdp); @@ -138,31 +147,6 @@ public void addResourceDescriptions(FDP fdp, Properties properties){ resourceTasksParents.stream().filter(ResourceUpdateInsertTask::hasChild).forEach(fdp::updateResource); } - public List filterSchemasToUpdate(FDP fdp, List shapeUpdateInsertTaskList) throws IOException { - logger.info("Getting all schemas with schema changes"); - - // Maps all schemas found with schema name as key for easy lookup. - Map existingSchemaMap = fdp.GetAllSchemas().stream() - .collect(Collectors.toMap( - SchemaDataResponse::name, - schema -> schema - )); - - List schemasToUpdate = new ArrayList<>(); - for (ShapeUpdateInsertTask task : shapeUpdateInsertTaskList) { - SchemaDataResponse existingSchema = existingSchemaMap.get(task.shape); - if (existingSchema == null) { - continue; - } - - if (!task.isSameSchema(existingSchema)){ - schemasToUpdate.add(task); - } - } - - return schemasToUpdate; - } - public enum CommandEnum { SCHEMA, RESOURCE, BOTH, TEMPLATE } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java index 8bc63ab..55a4487 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java @@ -2,18 +2,15 @@ import nl.healthri.fdp.uploadschema.FDP; import nl.healthri.fdp.uploadschema.Version; -import nl.healthri.fdp.uploadschema.requestresponses.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.RdfUtils; import org.eclipse.rdf4j.model.Model; +import org.eclipse.rdf4j.model.impl.LinkedHashModel; import org.eclipse.rdf4j.model.util.Models; -import org.eclipse.rdf4j.rio.RDFFormat; -import org.eclipse.rdf4j.rio.Rio; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.io.StringReader; import java.net.URI; import java.util.List; import java.util.NoSuchElementException; @@ -29,13 +26,17 @@ public class ShapeUpdateInsertTask { public String uuid; public Set parents; //name of parents for this schema. public String model; - public boolean exists = false; + public ShapeStatus status; + + public enum ShapeStatus { + INSERT, UPDATE, SAME + } public ShapeUpdateInsertTask(String shape) { this.shape = shape; } - public static List createTasks(Properties p, FDP fdp) { + public static List createTasks(Properties p, FDP fdp, FileHandler fileHandler) { final List Shapes = p.schemasToPublish; final var files = p.getFiles(); var shapesOnFdp = fdp.fetchSchemaFromFDP(); @@ -49,16 +50,18 @@ public static List createTasks(Properties p, FDP fdp) { logger.debug("loading model {} using turtle files: {} ", r, ttlFiles.stream().map(URI::toString).collect(Collectors.joining(", "))); - ShapeUpdateInsertTask.model = RdfUtils.modelAsTurtleString(RdfUtils.readFiles(ttlFiles)); + Model newModel = fileHandler.readFiles(ttlFiles); + ShapeUpdateInsertTask.model = RdfUtils.modelAsTurtleString(newModel); if (shapesOnFdp.isPresent(r)) { // todo: add current compare ttl schemas here - ShapeUpdateInsertTask.version = shapesOnFdp.getVersion(r).get().next(requestedVersion); //next patch version - ShapeUpdateInsertTask.uuid = shapesOnFdp.getUUID(r).get(); - ShapeUpdateInsertTask.exists = true; + Model onFdp = shapesOnFdp.getDefinition(r).map(RdfUtils::fromTurtleString).orElse(new LinkedHashModel()); + ShapeUpdateInsertTask.version = shapesOnFdp.getVersion(r).map(v -> v.next(requestedVersion)).orElseThrow(); //next patch version + ShapeUpdateInsertTask.uuid = shapesOnFdp.getUUID(r).orElseThrow(); + ShapeUpdateInsertTask.status = Models.isomorphic(onFdp, newModel) ? ShapeStatus.SAME : ShapeStatus.UPDATE; } else { ShapeUpdateInsertTask.version = requestedVersion; ShapeUpdateInsertTask.uuid = ""; - ShapeUpdateInsertTask.exists = false; + ShapeUpdateInsertTask.status = ShapeStatus.INSERT; } ShapeUpdateInsertTask.parents = p.getParents(r); return ShapeUpdateInsertTask; @@ -73,30 +76,7 @@ public String url() { return shape.toLowerCase().replaceAll(" ", ""); } - public boolean isInsert() { - return !exists; - } - - public boolean isSameSchema(SchemaDataResponse schemaData) throws IOException { - StringReader stringReaderNew; - if(this.model == null){ - stringReaderNew = new StringReader(""); - } else { - stringReaderNew = new StringReader(this.model); - } - - StringReader stringReaderOld; - if(schemaData.latest() == null){ - stringReaderOld = new StringReader(""); - } else { - stringReaderOld = new StringReader(schemaData.latest().definition()); - } - - // Parse TTL strings into RDF4J Models - Model taskModel = Rio.parse(stringReaderNew, "", RDFFormat.TURTLE); - Model schemaResponseModel = Rio.parse(stringReaderOld, "", RDFFormat.TURTLE); - - // Check if models have equivalent RDF Graphs to know if schema should be updated - return Models.isomorphic(taskModel, schemaResponseModel); + public ShapeStatus status() { + return status; } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java new file mode 100644 index 0000000..a181645 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java @@ -0,0 +1,123 @@ +package nl.healthri.fdp.uploadschema.utils; + +import org.eclipse.rdf4j.model.IRI; +import org.eclipse.rdf4j.model.Model; +import org.eclipse.rdf4j.model.Namespace; +import org.eclipse.rdf4j.model.Statement; +import org.eclipse.rdf4j.model.impl.LinkedHashModel; +import org.eclipse.rdf4j.rio.RDFFormat; +import org.eclipse.rdf4j.rio.RDFParser; +import org.eclipse.rdf4j.rio.RDFWriter; +import org.eclipse.rdf4j.rio.Rio; +import org.eclipse.rdf4j.rio.helpers.StatementCollector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.Duration; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +//this class handles RDF-File loading and saving this class should be +//injected in your class when you need it. Having it in a separate class +//simplifies testing. +public class FileHandler { + private static final Logger logger = LoggerFactory.getLogger(FileHandler.class); + + public void safeModel(Path p, Model m) throws IOException { + saveModelToStream(Files.newOutputStream(p), m); + } + + private void saveModelToStream(OutputStream out, Model m) { + RDFWriter writer = Rio.createWriter(RDFFormat.TURTLE, out); + writer.startRDF(); + + for (Namespace ns : m.getNamespaces()) { + writer.handleNamespace(ns.getPrefix(), ns.getName()); + } + for (Statement st : m) { + writer.handleStatement(st); + } + writer.endRDF(); + } + + public Model readFiles(List files) { + try { + logger.info("reading shacls from {}", files.getFirst().toString()); + RDFParser rdfParser = Rio.createParser(RDFFormat.TURTLE); + Model model = new LinkedHashModel(); + rdfParser.setRDFHandler(new StatementCollector(model)); + for (URI u : files) { + readFile(u, rdfParser); + } + validateNamespaces(model); + return model; + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } + + private void readFile(URI uri, RDFParser parser) throws IOException { + logger.debug("reading {}", uri.getPath()); + try { + InputStream fis = getInputStream(uri); + parser.parse(fis); + } catch (Exception e) { + logger.error(e.toString()); + } + } + + private InputStream getInputStream(URI uri) throws IOException { + + if (List.of("http", "https").contains(uri.getScheme().toLowerCase())) { + logger.trace("Fetch from github: {}", uri); + try (HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(5)).followRedirects(HttpClient.Redirect.NORMAL).build()) { + HttpRequest request = HttpRequest.newBuilder().uri(uri).GET().build(); + + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() / 100 == 2) { + return new ByteArrayInputStream(response.body().getBytes()); + } else { + throw new IOException("Failed to fetch file: " + response.statusCode()); + } + } catch (InterruptedException ie) { + throw new RuntimeException(ie); + } + } else { + return new FileInputStream(Paths.get(uri).toFile()); + } + } + + private void validateNamespaces(Model model) { + // Collect all namespaces used in the model + final Set usedNamespaces = model.stream() + .flatMap(st -> Set.of(st.getSubject(), st.getPredicate(), st.getObject()).stream()) + .filter(st -> st instanceof IRI) + .map(st -> ((IRI) st).getNamespace()) + .collect(Collectors.toSet()); + // Remove unused namespaces + Set namespacesToRemove = model.getNamespaces().stream() + .filter(ns -> !usedNamespaces.contains(ns.getName())) + .collect(Collectors.toSet()); + logger.info("Following namespace are unused: {}", namespacesToRemove); + + Set prefixes = model.getNamespaces().stream().map(Namespace::getPrefix).collect(Collectors.toSet()); + if (prefixes.size() != model.getNamespaces().size()) { + logger.warn("Duplicate prefixes found."); + } + Set names = model.getNamespaces().stream().map(Namespace::getName).collect(Collectors.toSet()); + if (names.size() != model.getNamespaces().size()) { + logger.warn("Duplicate namespace found."); + } + } + + +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java index fe68a53..bdc6576 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java @@ -1,139 +1,35 @@ package nl.healthri.fdp.uploadschema.utils; -import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.model.Model; -import org.eclipse.rdf4j.model.Namespace; -import org.eclipse.rdf4j.model.Statement; -import org.eclipse.rdf4j.model.impl.LinkedHashModel; import org.eclipse.rdf4j.rio.RDFFormat; -import org.eclipse.rdf4j.rio.RDFParser; -import org.eclipse.rdf4j.rio.RDFWriter; import org.eclipse.rdf4j.rio.Rio; -import org.eclipse.rdf4j.rio.helpers.StatementCollector; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.*; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.Duration; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; public class RdfUtils { - private static final Logger logger = LoggerFactory.getLogger(RdfUtils.class); private RdfUtils() { - //prevents instantiation + //prevent instantiation. } - private static void validateNamespaces(Model model) { - logger.info("validating namespaces {}", model.getNamespaces()); - - // Collect all namespaces used in the model - final Set usedNamespaces = model.stream() - .flatMap(st -> Set.of(st.getSubject(), st.getPredicate(), st.getObject()).stream()) - .filter(st -> st instanceof IRI) - .map(st -> ((IRI) st).getNamespace()) - .collect(Collectors.toSet()); - // Remove unused namespaces - Set namespacesToRemove = model.getNamespaces().stream() - .filter(ns -> !usedNamespaces.contains(ns.getName())) - .collect(Collectors.toSet()); - logger.info("Following namespace are unused: {}", namespacesToRemove); - - Set prefixes = model.getNamespaces().stream().map(Namespace::getPrefix).collect(Collectors.toSet()); - if (prefixes.size() != model.getNamespaces().size()) { - logger.warn("Duplicate prefixes found."); - } - Set names = model.getNamespaces().stream().map(Namespace::getName).collect(Collectors.toSet()); - if (names.size() != model.getNamespaces().size()) { - logger.warn("Duplicate namespace found."); - } - } - - private static void readFile(URI uri, RDFParser parser) throws IOException { - logger.info("reading {}", uri.getPath()); + public static Model fromTurtleString(String s) { try { - InputStream fis = getInputStream(uri); - parser.parse(fis); - } catch (Exception e) { - logger.error(e.toString()); - } - } - - public static Model readFiles(List files) { - logger.info("reading shacls from {}", files.getFirst().toString()); - - try { - RDFParser rdfParser = Rio.createParser(RDFFormat.TURTLE); - Model model = new LinkedHashModel(); - rdfParser.setRDFHandler(new StatementCollector(model)); - for (URI u : files) { - readFile(u, rdfParser); - } - validateNamespaces(model); - return model; + return Rio.parse(new StringReader(s), RDFFormat.TURTLE); } catch (IOException ioe) { + //will not happen because we are reading from string. throw new RuntimeException(ioe); } } - public static void printModelAsTurtle(Model m) { - saveModelToStream(System.out, m); - } - public static String modelAsTurtleString(Model m) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - saveModelToStream(out, m); - return out.toString(); - } - - public static void safeModel(Path p, Model m) throws IOException { - saveModelToStream(Files.newOutputStream(p), m); - } - - private static void saveModelToStream(OutputStream out, Model m) { - RDFWriter writer = Rio.createWriter(RDFFormat.TURTLE, out); - writer.startRDF(); - - for (Namespace ns : m.getNamespaces()) { - writer.handleNamespace(ns.getPrefix(), ns.getName()); - } - for (Statement st : m) { - writer.handleStatement(st); - } - writer.endRDF(); - } - - private static InputStream getInputStream(URI uri) throws IOException { - - if (List.of("http", "https").contains(uri.getScheme().toLowerCase())) { - logger.trace("Fetch from github: {}", uri); - try (HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(5)).followRedirects(HttpClient.Redirect.NORMAL).build()) { - HttpRequest request = HttpRequest.newBuilder().uri(uri).GET().build(); - - HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); - if (response.statusCode() / 100 == 2) { - return new ByteArrayInputStream(response.body().getBytes()); - } else { - throw new IOException("Failed to fetch file: " + response.statusCode()); - } - } catch (InterruptedException ie) { - throw new RuntimeException(ie); - } - } else { - return new FileInputStream(Paths.get(uri).toFile()); - } + StringWriter sw = new StringWriter(); + Rio.write(m, sw, RDFFormat.TURTLE); + return sw.toString(); } - public static String schemaToFile(String name) { + public static String schemaToFilename(String name) { return name.replaceAll(" ", "") + ".ttl"; } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java index bc455a3..9e7e5eb 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java @@ -12,7 +12,11 @@ public class ShapesMap extends ObjectMap { public ShapesMap(SchemaDataResponse[] repsonses) { this.map = Arrays .stream(repsonses) - .collect(Collectors.toMap(SchemaDataResponse::name, sr -> new SchemaInfo(new Version(sr.latest().version()), sr.uuid()))); + .collect(Collectors.toMap(SchemaDataResponse::name, sr -> new SchemaInfo(new Version(sr.latest().version()), sr.uuid(), sr.latest().definition()))); + } + + public Optional getDefinition(String name) { + return getValue(name).map(SchemaInfo::definition); } public Optional getVersion(String name) { @@ -23,6 +27,6 @@ public Optional getUUID(String name) { return getValue(name).map(SchemaInfo::uuid); } - public record SchemaInfo(Version version, String uuid) { + public record SchemaInfo(Version version, String uuid, String definition) { } } diff --git a/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java b/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java new file mode 100644 index 0000000..27541fa --- /dev/null +++ b/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java @@ -0,0 +1,214 @@ +package nl.healthri.fdp.uploadschema.tasks; + +import nl.healthri.fdp.uploadschema.FDP; +import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.requestresponses.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.utils.FileHandler; +import nl.healthri.fdp.uploadschema.utils.Properties; +import nl.healthri.fdp.uploadschema.utils.RdfUtils; +import nl.healthri.fdp.uploadschema.utils.ShapesMap; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.net.URI; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ShapeUpdateInsertTaskTest { + + /** + * Tests the functionality of the `ShapeUpdateInsertTask.createTasks` + * The test uses mocking to simulate: + *

+ * - Fetching schema data from an FDP (Fair Data Point). + * - RDF model reading from files via a `FileHandler`. + *

+ * The schema is present on FDP, but the schema of the file is different + * so the task will be labeled with "UPDATE" + */ + @Test + void testCreateTasks_updated_shape() { + // Mock Properties + Properties props = Mockito.mock(Properties.class); + props.schemasToPublish = List.of("TestShape"); + Mockito.when(props.getFiles()).thenReturn(Map.of("TestShape", List.of(URI.create("file:test.ttl")))); + Mockito.when(props.getVersion()).thenReturn(new Version("2.0.0")); + Mockito.when(props.getParents("TestShape")).thenReturn(Set.of("ParentShape")); + + // Mock FDP and its fetchSchemaFromFDP result + ShapesMap shapesOnFdp = createFdpShapeMap( + createFdpResponse("TestShape", "", "1.0.0", "uuid")); + + FDP fdp = Mockito.mock(FDP.class); + Mockito.when(fdp.fetchSchemaFromFDP()).thenReturn(shapesOnFdp); + + // Mock FileHandler + FileHandler fileHandler = Mockito.mock(FileHandler.class); + Mockito.when(fileHandler.readFiles(Mockito.anyList())).thenReturn(RdfUtils.fromTurtleString(getShapeModel2())); + + // Run createTasks + List tasks = ShapeUpdateInsertTask.createTasks(props, fdp, fileHandler); + + // Assert + assertEquals(1, tasks.size()); + ShapeUpdateInsertTask task = tasks.getFirst(); + assertEquals("TestShape", task.shape); + assertEquals(new Version("2.0.0"), task.version); + assertEquals(getShapeModel2(), task.model); + assertEquals(ShapeUpdateInsertTask.ShapeStatus.UPDATE, task.status); + } + + /** + * Tests the functionality of the `ShapeUpdateInsertTask.createTasks` + * The test uses mocking to simulate: + *

+ * - Fetching schema data from an FDP (Fair Data Point). + * - RDF model reading from files via a `FileHandler`. + *

+ * The schema is on FDP and is the same as from the file. So it the task will be labeled with "SAME" + */ + @Test + void testCreateTasks_identical_shape() { + // Mock Properties + Properties props = Mockito.mock(Properties.class); + props.schemasToPublish = List.of("TestShape"); + Mockito.when(props.getFiles()).thenReturn(Map.of("TestShape", List.of(URI.create("file:test.ttl")))); + Mockito.when(props.getVersion()).thenReturn(new Version("2.0.0")); + Mockito.when(props.getParents("TestShape")).thenReturn(Set.of("ParentShape")); + + // Mock FDP and its fetchSchemaFromFDP result + ShapesMap shapesOnFdp = createFdpShapeMap( + createFdpResponse("TestShape", getShapeModel1(), "1.0.0", "uuid")); + + FDP fdp = Mockito.mock(FDP.class); + Mockito.when(fdp.fetchSchemaFromFDP()).thenReturn(shapesOnFdp); + + // Mock FileHandler + FileHandler fileHandler = Mockito.mock(FileHandler.class); + Mockito.when(fileHandler.readFiles(Mockito.anyList())).thenReturn(RdfUtils.fromTurtleString(getShapeModel1())); + + // Run createTasks + List tasks = ShapeUpdateInsertTask.createTasks(props, fdp, fileHandler); + + // Assert + assertEquals(1, tasks.size()); + ShapeUpdateInsertTask task = tasks.getFirst(); + assertEquals("TestShape", task.shape); + assertEquals(new Version("2.0.0"), task.version); + assertEquals(getShapeModel1(), task.model); + assertEquals(ShapeUpdateInsertTask.ShapeStatus.SAME, task.status); + } + + /** + * Tests the functionality of the `ShapeUpdateInsertTask.createTasks` + * The test uses mocking to simulate: + *

+ * - Fetching schema data from an FDP (Fair Data Point). + * - RDF model reading from files via a `FileHandler`. + *

+ * The schema is not present on the FDP, so the task will be labeled with "SAME" + */ + @Test + void testCreateTasks_new() { + // Mock Properties + Properties props = Mockito.mock(Properties.class); + props.schemasToPublish = List.of("TestShape"); + Mockito.when(props.getFiles()).thenReturn(Map.of("TestShape", List.of(URI.create("file:test.ttl")))); + Mockito.when(props.getVersion()).thenReturn(new Version("2.0.0")); + Mockito.when(props.getParents("TestShape")).thenReturn(Set.of("ParentShape")); + + // Mock FDP and its fetchSchemaFromFDP result + ShapesMap shapesOnFdp = createFdpShapeMap( + createFdpResponse("JustAnotherShape", "", "1.0.0", "uuid")); + + FDP fdp = Mockito.mock(FDP.class); + Mockito.when(fdp.fetchSchemaFromFDP()).thenReturn(shapesOnFdp); + + // Mock FileHandler + FileHandler fileHandler = Mockito.mock(FileHandler.class); + Mockito.when(fileHandler.readFiles(Mockito.anyList())).thenReturn(RdfUtils.fromTurtleString(getShapeModel2())); + + // Run createTasks + List tasks = ShapeUpdateInsertTask.createTasks(props, fdp, fileHandler); + + // Assert + assertEquals(1, tasks.size()); + ShapeUpdateInsertTask task = tasks.getFirst(); + assertEquals("TestShape", task.shape); + assertEquals(new Version("2.0.0"), task.version); + assertEquals(getShapeModel2(), task.model); + assertEquals(ShapeUpdateInsertTask.ShapeStatus.INSERT, task.status); + } + + private ShapesMap createFdpShapeMap(SchemaDataResponse... responses) { + return new ShapesMap(responses); + } + + private SchemaDataResponse createFdpResponse(String name, String definition, String version, String uuid) { + SchemaDataResponse.Latest latest = new SchemaDataResponse.Latest(uuid, + version, uuid, + "", + name, true, false, true, + "", "", "", definition, "", null, null, "", ""); + + return new SchemaDataResponse(uuid, name, latest, null, null, null, null); + } + + private String getShapeModel1() { + return linter(""" + @prefix ex: . + @prefix sh: . + @prefix xsd: . + @prefix foaf: . + + ex:PersonShape a sh:NodeShape ; + sh:targetClass foaf:Person ; + sh:property ex:NamePropertyShape ; + sh:property ex:AgePropertyShape . + + ex:NamePropertyShape a sh:PropertyShape ; + sh:path foaf:name ; + sh:datatype xsd:string ; + sh:minCount 1 . + + ex:AgePropertyShape a sh:PropertyShape ; + sh:path foaf:age ; + sh:datatype xsd:integer ; + sh:minInclusive 0 ; + sh:maxCount 1 ."""); + } + + private String linter(String s) { + //make sure the model is properly formatted + return RdfUtils.modelAsTurtleString(RdfUtils.fromTurtleString(s)); + } + + private String getShapeModel2() { + + return linter(""" + @prefix ex: . + @prefix sh: . + @prefix xsd: . + @prefix foaf: . + + ex:PersonShape a sh:NodeShape ; + sh:targetClass foaf:Person ; + sh:property ex:NamePropertyShape ; + sh:property ex:AgePropertyShape . + + ex:NamePropertyShape a sh:PropertyShape ; + sh:path foaf:name ; + sh:datatype xsd:string ; + sh:minCount 100 . + + ex:AgePropertyShape a sh:PropertyShape ; + sh:path foaf:age ; + sh:datatype xsd:integer ; + sh:minInclusive 0 ; + sh:maxCount 1 ."""); + } +} + From 6e6f0a52262bc9738e51a1c8649253c9fb0acb88 Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Wed, 22 Oct 2025 14:23:42 +0200 Subject: [PATCH 05/51] Feat: Added improved error handling for reading and formatting properties files. --- .../nl/healthri/fdp/uploadschema/FDP.java | 2 +- .../fdp/uploadschema/utils/RdfUtils.java | 22 +++++++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/FDP.java b/src/main/java/nl/healthri/fdp/uploadschema/FDP.java index 954a48f..c0c3cb9 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/FDP.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/FDP.java @@ -205,7 +205,7 @@ public List GetAllSchemas(){ // Handle each response based on Fair Data Point (FDP) Swagger documentation. switch (response.statusCode()) { - case 200 -> logger.info("OK"); + case 200 -> logger.info("Successfully received all schemas from FDP"); case 400 -> throw new IllegalArgumentException(String.valueOf(HttpStatus.SC_BAD_REQUEST)); case 401 -> diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java index fe68a53..a8a4c29 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java @@ -5,10 +5,7 @@ import org.eclipse.rdf4j.model.Namespace; import org.eclipse.rdf4j.model.Statement; import org.eclipse.rdf4j.model.impl.LinkedHashModel; -import org.eclipse.rdf4j.rio.RDFFormat; -import org.eclipse.rdf4j.rio.RDFParser; -import org.eclipse.rdf4j.rio.RDFWriter; -import org.eclipse.rdf4j.rio.Rio; +import org.eclipse.rdf4j.rio.*; import org.eclipse.rdf4j.rio.helpers.StatementCollector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -60,11 +57,16 @@ private static void validateNamespaces(Model model) { private static void readFile(URI uri, RDFParser parser) throws IOException { logger.info("reading {}", uri.getPath()); + try { InputStream fis = getInputStream(uri); parser.parse(fis); - } catch (Exception e) { - logger.error(e.toString()); + } catch (IOException e) { + throw new IOException("I/O error while reading the file: " + uri, e); + } catch (RDFParseException e) { + throw new IOException("Error parsing RDF file - invalid Turtle syntax: " + uri, e); + } catch (RDFHandlerException e) { + throw new IOException("Error while processing RDF content from file: " + uri, e); } } @@ -80,15 +82,11 @@ public static Model readFiles(List files) { } validateNamespaces(model); return model; - } catch (IOException ioe) { - throw new RuntimeException(ioe); + } catch (IOException e) { + throw new RuntimeException("Failed to read SHACL files: " + files, e); } } - public static void printModelAsTurtle(Model m) { - saveModelToStream(System.out, m); - } - public static String modelAsTurtleString(Model m) { ByteArrayOutputStream out = new ByteArrayOutputStream(); saveModelToStream(out, m); From 7281e57d706722d1db5b19d82612913581197dc2 Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Wed, 22 Oct 2025 14:40:47 +0200 Subject: [PATCH 06/51] Merged: merged with feature-compare-schema-before-update --- .../fdp/uploadschema/utils/FileHandler.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java index a181645..89ad0c7 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java @@ -5,10 +5,7 @@ import org.eclipse.rdf4j.model.Namespace; import org.eclipse.rdf4j.model.Statement; import org.eclipse.rdf4j.model.impl.LinkedHashModel; -import org.eclipse.rdf4j.rio.RDFFormat; -import org.eclipse.rdf4j.rio.RDFParser; -import org.eclipse.rdf4j.rio.RDFWriter; -import org.eclipse.rdf4j.rio.Rio; +import org.eclipse.rdf4j.rio.*; import org.eclipse.rdf4j.rio.helpers.StatementCollector; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,9 +46,11 @@ private void saveModelToStream(OutputStream out, Model m) { writer.endRDF(); } + public Model readFiles(List files) { + logger.info("reading and parsing Shacl from {}", files.getFirst().toString()); + try { - logger.info("reading shacls from {}", files.getFirst().toString()); RDFParser rdfParser = Rio.createParser(RDFFormat.TURTLE); Model model = new LinkedHashModel(); rdfParser.setRDFHandler(new StatementCollector(model)); @@ -60,18 +59,22 @@ public Model readFiles(List files) { } validateNamespaces(model); return model; - } catch (IOException ioe) { - throw new RuntimeException(ioe); + } catch (IOException e) { + throw new RuntimeException("Failed to read SHACL files: " + files, e); } } + private void readFile(URI uri, RDFParser parser) throws IOException { - logger.debug("reading {}", uri.getPath()); try { InputStream fis = getInputStream(uri); parser.parse(fis); - } catch (Exception e) { - logger.error(e.toString()); + } catch (IOException e) { + throw new IOException("I/O error while reading the file: " + uri, e); + } catch (RDFParseException e) { + throw new IOException("Error parsing RDF file - invalid Turtle syntax: " + uri, e); + } catch (RDFHandlerException e) { + throw new IOException("Error while processing RDF content from file: " + uri, e); } } From a53fd289fde500c54cadef14c7c57c78c0aac8a9 Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Thu, 23 Oct 2025 09:27:55 +0200 Subject: [PATCH 07/51] Merged: merged with feature-compare-schema-before-update --- .../fdp/uploadschema/SchemaTools.java | 1 + .../tasks/ShapeUpdateInsertTask.java | 3 +- .../fdp/uploadschema/utils/FileHandler.java | 9 +- .../uploadschema/utils/SchemaToolsTest.java | 225 ------------------ 4 files changed, 9 insertions(+), 229 deletions(-) delete mode 100644 src/test/java/nl/healthri/fdp/uploadschema/utils/SchemaToolsTest.java diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index 6841f50..3cdc53d 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -64,6 +64,7 @@ public void run() { mergeShapesForValidation(properties, fileHandler); } case BOTH -> { + // TODO: create Constructor with fdp dependency injector createOrUpdateSchemas(fdp, properties, force, fileHandler); addResourceDescriptions(fdp, properties); } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java index 55a4487..e3f616e 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java @@ -11,6 +11,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; import java.net.URI; import java.util.List; import java.util.NoSuchElementException; @@ -36,7 +37,7 @@ public ShapeUpdateInsertTask(String shape) { this.shape = shape; } - public static List createTasks(Properties p, FDP fdp, FileHandler fileHandler) { + public static List createTasks(Properties p, FDP fdp, FileHandler fileHandler){ final List Shapes = p.schemasToPublish; final var files = p.getFiles(); var shapesOnFdp = fdp.fetchSchemaFromFDP(); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java index 89ad0c7..05078dc 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java @@ -47,7 +47,7 @@ private void saveModelToStream(OutputStream out, Model m) { } - public Model readFiles(List files) { + public Model readFiles(List files){ logger.info("reading and parsing Shacl from {}", files.getFirst().toString()); try { @@ -60,7 +60,10 @@ public Model readFiles(List files) { validateNamespaces(model); return model; } catch (IOException e) { - throw new RuntimeException("Failed to read SHACL files: " + files, e); + String fileList = files.stream() + .map(URI::toString) + .collect(Collectors.joining(", ")); + throw new RuntimeException("Failed to read files: " + fileList, e); } } @@ -70,7 +73,7 @@ private void readFile(URI uri, RDFParser parser) throws IOException { InputStream fis = getInputStream(uri); parser.parse(fis); } catch (IOException e) { - throw new IOException("I/O error while reading the file: " + uri, e); + throw new IOException("Error while reading file: " + uri, e); } catch (RDFParseException e) { throw new IOException("Error parsing RDF file - invalid Turtle syntax: " + uri, e); } catch (RDFHandlerException e) { diff --git a/src/test/java/nl/healthri/fdp/uploadschema/utils/SchemaToolsTest.java b/src/test/java/nl/healthri/fdp/uploadschema/utils/SchemaToolsTest.java deleted file mode 100644 index 05e1474..0000000 --- a/src/test/java/nl/healthri/fdp/uploadschema/utils/SchemaToolsTest.java +++ /dev/null @@ -1,225 +0,0 @@ -package nl.healthri.fdp.uploadschema.utils; - -import nl.healthri.fdp.uploadschema.FDP; -import nl.healthri.fdp.uploadschema.SchemaTools; -import nl.healthri.fdp.uploadschema.requestresponses.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.*; - -public class SchemaToolsTest { - - private SchemaTools schemaTools; - @Mock - private FDP mockFdp; - - // Initialize Mockito mocks before each test - @BeforeEach - void setUp() { - // Must initialize mocks defined with @Mock - MockitoAnnotations.openMocks(this); - schemaTools = new SchemaTools(); - } - - private ShapeUpdateInsertTask createMockTask(String shapeName, boolean isInsert, boolean isSameSchemaResult) throws IOException { - ShapeUpdateInsertTask realTask = new ShapeUpdateInsertTask(shapeName); - ShapeUpdateInsertTask spyTask = spy(realTask); - doReturn(isInsert).when(spyTask).isInsert(); - - if (!isInsert) { - doReturn(isSameSchemaResult).when(spyTask).isSameSchema(any(SchemaDataResponse.class)); - } - - return spyTask; - } - - // Creates a SchemaDataResponse. - private SchemaDataResponse createSchemaResponse(String name) { - SchemaDataResponse mockSchemaDataResponse = mock(SchemaDataResponse.class); - - doReturn(name).when(mockSchemaDataResponse).name(); - return mockSchemaDataResponse; - } - - /** - * Condition: Existing schema map is empty. - * Expected: No updates, as any non-insert task won't find an existing schema. - */ - @Test - void filterSchemasToUpdate_NoExistingSchemas_ReturnsEmptyList() throws IOException { - // Arrange - when(mockFdp.GetAllSchemas()).thenReturn(Collections.emptyList()); - - ShapeUpdateInsertTask taskA = createMockTask("SchemaA", false, false); - List inputTasks = Collections.singletonList(taskA); - - // Act - List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); - - // Assert - assertTrue(result.isEmpty(), "Tasks should be filtered out when no existing schemas are found."); - verify(taskA, never()).isSameSchema(any()); - } - - - /** - * Condition: The input list of tasks is empty. - * Expected: Empty result list. - */ - @Test - void filterSchemasToUpdate_EmptyInputTaskList_ReturnsEmptyList() throws IOException { - // Arrange - List existingSchemas = Collections.singletonList(createSchemaResponse("SchemaA")); - when(mockFdp.GetAllSchemas()).thenReturn(existingSchemas); - List inputTasks = new ArrayList<>(); - - // Act - List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); - - // Assert - assertTrue(result.isEmpty(), "Result should be empty when the input task list is empty."); - } - - /** - * Condition: A task's 'isInsert()' method returns true. - * Expected: Insert tasks must be filtered out (ignored). - */ - @Test - void filterSchemasToUpdate_TaskIsInsert_TaskIsFilteredOut() throws IOException { - // Arrange - List existingSchemas = Collections.singletonList(createSchemaResponse("SchemaA")); - when(mockFdp.GetAllSchemas()).thenReturn(existingSchemas); - - ShapeUpdateInsertTask insertTask = createMockTask("SchemaA", true, false); - List inputTasks = Collections.singletonList(insertTask); - - // Act - List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); - - // Assert - assertTrue(result.isEmpty(), "Insert task should be filtered out."); - verify(insertTask, times(1)).isSameSchema(any()); - } - - /** - * Condition: Task is an update, but its shape name is not found in the existing map. - * Expected: Task must be filtered out. - */ - @Test - void filterSchemasToUpdate_ExistingSchemaNotFound_TaskIsFilteredOut() throws IOException { - // Arrange - List existingSchemas = Collections.singletonList(createSchemaResponse("SchemaA")); - when(mockFdp.GetAllSchemas()).thenReturn(existingSchemas); - - // Task is for SchemaB (update, but not found) - ShapeUpdateInsertTask nonExistingTask = createMockTask("SchemaB", false, false); - List inputTasks = Collections.singletonList(nonExistingTask); - - // Act - List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); - - // Assert - assertTrue(result.isEmpty(), "Task targeting a non-existing schema should be filtered out."); - verify(nonExistingTask, never()).isSameSchema(any()); - } - - /** - * Condition: Task is an update, schema exists, and 'isSameSchema' returns false. - * Expected: Task should be included in the result. - */ - @Test - void filterSchemasToUpdate_ExistingSchemaIsDifferent_TaskIsIncluded() throws IOException { - // Arrange - SchemaDataResponse existingSchemaA = createSchemaResponse("SchemaA"); - when(mockFdp.GetAllSchemas()).thenReturn(Collections.singletonList(existingSchemaA)); - - // Task reports *not* being the same schema (false means different/needs update) - ShapeUpdateInsertTask differentTaskA = createMockTask("SchemaA", false, false); - List inputTasks = Collections.singletonList(differentTaskA); - - // Act - List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); - - // Assert - assertEquals(1, result.size(), "Task for a different schema should be included."); - assertEquals(differentTaskA, result.getFirst()); - verify(differentTaskA, times(1)).isSameSchema(existingSchemaA); - } - - /** - * Condition: Task is an update, schema exists, and 'isSameSchema' returns true. - * Expected: Task should be filtered out (no update needed). - */ - @Test - void filterSchemasToUpdate_ExistingSchemaIsSame_TaskIsFilteredOut() throws IOException { - // Arrange - SchemaDataResponse existingSchemaA = createSchemaResponse("SchemaA"); - when(mockFdp.GetAllSchemas()).thenReturn(Collections.singletonList(existingSchemaA)); - - // Task reports being the same schema (true means no change) - ShapeUpdateInsertTask sameTaskA = createMockTask("SchemaA", false, true); - List inputTasks = Collections.singletonList(sameTaskA); - - // Act - List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); - - // Assert - assertTrue(result.isEmpty(), "Task for a schema with the same content should be filtered out."); - verify(sameTaskA, times(1)).isSameSchema(existingSchemaA); - } - - /** - * Condition: Input list contains inserts, non-existent targets, same-content updates, and different-content updates. - * Expected: Only the tasks requiring updates should be returned. - */ - @Test - void filterSchemasToUpdate_MixedTasks_ReturnsOnlyNecessaryUpdates() throws IOException { - // Arrange - SchemaDataResponse existingA = createSchemaResponse("SchemaA"); - SchemaDataResponse existingB = createSchemaResponse("SchemaB"); - SchemaDataResponse existingC = createSchemaResponse("SchemaC"); - - List existingSchemas = Arrays.asList(existingA, existingB, existingC); - when(mockFdp.GetAllSchemas()).thenReturn(existingSchemas); - - ShapeUpdateInsertTask insertTask = createMockTask("SchemaD", true, false); // 1. Filtered out (Insert) - ShapeUpdateInsertTask nonExistingTask = createMockTask("SchemaE", false, false); // 2. Filtered out (Non-existing target) - ShapeUpdateInsertTask sameTask = createMockTask("SchemaA", false, true); // 3. Filtered out (Same content) - ShapeUpdateInsertTask differentTask1 = createMockTask("SchemaB", false, false); // 4. Included (Different content) - ShapeUpdateInsertTask differentTask2 = createMockTask("SchemaC", false, false); // 5. Included (Different content) - - List inputTasks = Arrays.asList( - insertTask, - nonExistingTask, - sameTask, - differentTask1, - differentTask2 - ); - - // Act - List result = schemaTools.filterSchemasToUpdate(mockFdp, inputTasks); - - // Assert - assertEquals(2, result.size(), "Only two tasks (B and C) should be included."); - assertTrue(result.contains(differentTask1)); - assertTrue(result.contains(differentTask2)); - - verify(insertTask, times(0)).isSameSchema(existingB); - verify(nonExistingTask, times(0)).isSameSchema(existingC); - verify(sameTask, times(1)).isSameSchema(existingA); - verify(differentTask1, times(1)).isSameSchema(existingB); - verify(differentTask2, times(1)).isSameSchema(existingC); - } -} \ No newline at end of file From c15aa918433949cc7afe05d8ecc834f525e19724 Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Fri, 24 Oct 2025 16:50:07 +0200 Subject: [PATCH 08/51] Refactor: Code simplified and improved readability and maintainability. - removed redundant custom request builder, Java request library already has a builder which leaded to unnessesary complexity. - Added improved general response handling based on swagger documentation of FDP. - Changed timeout from 500ms to 30000ms, this was causing requests not to be made and because of limited error handling not noticed either. - Added integration folder for external API integrations (FDP) - Added DTO's with Requests and Responses - Removed unused code - Renamed files for naming consistency --- .../nl/healthri/fdp/uploadschema/FDP.java | 241 ----------- .../fdp/uploadschema/SchemaTools.java | 6 +- .../dto/request/LoginRequest.java | 5 + .../request/ReleaseSchemaRequest.java} | 8 +- .../dto/request/ResourceRequest.java | 17 + .../request/UpdateSchemaRequest.java} | 4 +- .../response}/ResourceResponse.java | 2 +- .../response}/SchemaDataResponse.java | 2 +- .../response}/TokenResponse.java | 2 +- .../dto/response/UpdateResourceResponse.java | 21 + .../response/UpdateSchemaResponse.java} | 4 +- .../fdp/uploadschema/integration/FDP.java | 386 ++++++++++++++++++ .../requestbodies/ResourceParms.java | 17 - .../requestbodies/SchemaParms.java | 7 - .../requestbodies/loginParms.java | 5 - .../requestresponses/FDPInfoResponse.java | 10 - .../ResourceEditResponse.java | 21 - .../tasks/ResourceUpdateInsertTask.java | 8 +- .../tasks/ShapeUpdateInsertTask.java | 11 +- .../uploadschema/utils/HttpRequestUtils.java | 27 ++ .../uploadschema/utils/RequestBuilder.java | 113 ----- .../fdp/uploadschema/utils/ResourceMap.java | 2 +- .../fdp/uploadschema/utils/ShapesMap.java | 2 +- .../{ => utils}/XlsToRdfUtils.java | 2 +- .../tasks/ShapeUpdateInsertTaskTest.java | 10 +- 25 files changed, 488 insertions(+), 445 deletions(-) delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/FDP.java create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/dto/request/LoginRequest.java rename src/main/java/nl/healthri/fdp/uploadschema/{requestbodies/ReleaseSchemaParms.java => dto/request/ReleaseSchemaRequest.java} (54%) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/dto/request/ResourceRequest.java rename src/main/java/nl/healthri/fdp/uploadschema/{requestbodies/EditSchemaParms.java => dto/request/UpdateSchemaRequest.java} (74%) rename src/main/java/nl/healthri/fdp/uploadschema/{requestresponses => dto/response}/ResourceResponse.java (93%) rename src/main/java/nl/healthri/fdp/uploadschema/{requestresponses => dto/response}/SchemaDataResponse.java (94%) rename src/main/java/nl/healthri/fdp/uploadschema/{requestresponses => dto/response}/TokenResponse.java (69%) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/dto/response/UpdateResourceResponse.java rename src/main/java/nl/healthri/fdp/uploadschema/{requestresponses/SchemaEdit.java => dto/response/UpdateSchemaResponse.java} (77%) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/integration/FDP.java delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/requestbodies/ResourceParms.java delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/requestbodies/SchemaParms.java delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/requestbodies/loginParms.java delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/requestresponses/FDPInfoResponse.java delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/requestresponses/ResourceEditResponse.java create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/utils/HttpRequestUtils.java delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/utils/RequestBuilder.java rename src/main/java/nl/healthri/fdp/uploadschema/{ => utils}/XlsToRdfUtils.java (98%) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/FDP.java b/src/main/java/nl/healthri/fdp/uploadschema/FDP.java deleted file mode 100644 index c0c3cb9..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/FDP.java +++ /dev/null @@ -1,241 +0,0 @@ -package nl.healthri.fdp.uploadschema; - -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import nl.healthri.fdp.uploadschema.requestbodies.*; -import nl.healthri.fdp.uploadschema.requestresponses.*; -import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; -import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; -import nl.healthri.fdp.uploadschema.utils.RequestBuilder; -import nl.healthri.fdp.uploadschema.utils.ResourceMap; -import nl.healthri.fdp.uploadschema.utils.ShapesMap; -import org.apache.http.HttpStatus; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.helpers.MessageFormatter; - -import java.io.IOException; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.time.Duration; -import java.time.temporal.ChronoUnit; -import java.util.*; -import java.util.stream.Collectors; - -public class FDP implements AutoCloseable { - private static final Logger logger = LoggerFactory.getLogger(FDP.class); - - private final String url; - private final ObjectMapper mapper; - private final HttpClient client; - private TokenResponse token; - - private FDP(URI url) { - this.url = url.toString(); - this.mapper = new ObjectMapper(new JsonFactory()); - this.client = HttpClient.newBuilder() - .followRedirects(HttpClient.Redirect.NORMAL) - .connectTimeout(Duration.of(500, ChronoUnit.MILLIS)) - .build(); - } - - public static FDP connectToFdp(URI url, String username, String password) { - logger.info("Connecting to FDP at {} as {} ", url, username); - - FDP fdp = new FDP(url); - var info = fdp.request().setUri(fdp.url("actuator/info")).get(FDPInfoResponse.class); - logger.info("FDP info: {}", info.toString()); - - var mp = new loginParms(username, password); - var token = fdp.request().setUri(fdp.url("tokens")).setBody(mp).post(TokenResponse.class); - - logger.info("Token received: {}", token); - fdp.token = token; - - return fdp; - } - - private String url(String path) { - return MessageFormatter.format("{}/{}", url, path).getMessage(); - } - - private String url(String path, String uuid) { - return MessageFormatter.arrayFormat("{}/{}/{}", new Object[]{url, path, uuid}).getMessage(); - } - - private Set getParentUID(Set shapes) { - if (shapes.isEmpty()) { - return Collections.emptySet(); - } - var shapesOnFdp = fetchSchemaFromFDP(); - return shapes.stream() - .map(shapesOnFdp::getUUID).flatMap(Optional::stream) - .collect(Collectors.toSet()); - } - - public RequestBuilder request() { - return new RequestBuilder(mapper, client); - - } - - public ShapesMap fetchSchemaFromFDP() { - logger.info("Fetch schema info from fdp"); - var sp = new SchemaParms(false, true); - SchemaDataResponse[] schemas = request().setUri(url + "/metadata-schemas", sp) - .setBody(sp).setToken(token).get(SchemaDataResponse[].class); - return new ShapesMap(schemas); - } - - public ResourceMap fetchResourceFromFDP() { - logger.info("Fetch resource info from fdp"); - ResourceResponse[] resources = request().setUri(url + "/resource-definitions") - .setToken(token).get(ResourceResponse[].class); - - return new ResourceMap(resources); - } - - public void insertResource(ResourceUpdateInsertTask task) { - logger.info("Insert {} resource into the fdp", task.resource); - ResourceParms RP = new ResourceParms( - task.resource, - task.url(), - new ArrayList<>(List.of(task.shapeUUUID)), - new ArrayList<>(), - new ArrayList<>(), - new ArrayList<>()); - ResourceResponse rer = request().setUri(url("resource-definitions")) - .setBody(RP) - .setToken(token).post(ResourceResponse.class); - task.UUID = rer.uuid(); - } - - public void updateResource(ResourceUpdateInsertTask task) { - logger.info("fetch resource {} from fdp", task.resource); - var rr = request() - .setToken(token) - .setUri(url("resource-definitions", task.UUID)) - .get(ResourceResponse.class); - - if (rr.children().stream().anyMatch(c -> c.resourceDefinitionUuid().equals(task.childUUuid))) { - logger.warn("resource {} already has link to child {}", rr.name(), task.childName); - } else { - //FIXME TagsURI is hardcoded.. - var child = new ResourceResponse.Child(task.childUUuid, task.childRelationIri, - new ResourceResponse.ListView(task.pluralName(), "http://www.w3.org/ns/dcat#themeTaxonomy", new ArrayList<>())); - rr.children().add(child); - } - - logger.info("update resource {} on the fdp", task.resource); - request().setToken(token) - .setUri(url("resource-definitions", task.UUID)) - .setBody(rr) - .put(ResourceResponse.class); - } - - /** - * @param t task, with info about the shape to create, - * when the shapes are created it will update this parameter by setting the UUID! - */ - public void insertSchema(ShapeUpdateInsertTask t) { - logger.info("Insert {} shape into the fdp", t.shape); - EditSchemaParms esp = new EditSchemaParms(t.shape, - t.description(), false, - t.model, getParentUID(t.parents), - t.shape, - t.url()); - - SchemaEdit se = request().setUri(url + "/metadata-schemas") - .setBody(esp) - .setToken(token) - .post(SchemaEdit.class); - t.uuid = se.uuid(); - } - - /** - * update exiting shape on the fdp - * - * @param t task, with shape information - */ - - public void updateSchema(ShapeUpdateInsertTask t) { - logger.info("Update {} into the fdp", t.shape); - EditSchemaParms esp = new EditSchemaParms(t.shape, - t.description(), false, - t.model, getParentUID(t.parents), - t.shape, - t.url()); - - //result of request is not needed - request().setUri(url + "/metadata-schemas/" + t.uuid + "/draft") - .setBody(esp) - .setToken(token) - .put(SchemaEdit.class); - } - - public void releaseSchema(ShapeUpdateInsertTask t) { - logger.info("Release {} into the fdp", t.shape); - ReleaseSchemaParms rsp = ReleaseSchemaParms.of(t.shape, - false, t.version); -// result of request is not needed. - request().setUri(url + "/metadata-schemas/" + t.uuid + "/versions") - .setBody(rsp) - .setToken(token) - .post(SchemaDataResponse.class); - } - - - public List GetAllSchemas(){ - logger.info("Getting all metadata schemas"); - try { - HttpClient client = HttpClient.newBuilder() - .build(); - - HttpRequest request = HttpRequest.newBuilder() - .GET() - .uri(new URI(url + "/metadata-schemas/")) - .header("accept", "application/json") - .header("Content-Type", "application/json") - .header("Authorization", String.valueOf(token)) - .build(); - - HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); - - // Handle each response based on Fair Data Point (FDP) Swagger documentation. - switch (response.statusCode()) { - case 200 -> logger.info("Successfully received all schemas from FDP"); - case 400 -> - throw new IllegalArgumentException(String.valueOf(HttpStatus.SC_BAD_REQUEST)); - case 401 -> - throw new SecurityException(String.valueOf(HttpStatus.SC_UNAUTHORIZED)); - case 403 -> - throw new SecurityException(String.valueOf(HttpStatus.SC_FORBIDDEN)); - case 404 -> - throw new IOException(String.valueOf(HttpStatus.SC_NOT_FOUND)); - case 500 -> - throw new IOException(String.valueOf(HttpStatus.SC_INTERNAL_SERVER_ERROR)); - default -> { - throw new RuntimeException("Unexpected HTTP status: " + response.statusCode()); - } - } - - ObjectMapper objectMapper = new ObjectMapper(); - TypeReference> schemaDataTypeReference = new TypeReference>(){}; - List schemaDataResponseList = objectMapper.readValue(response.body(), schemaDataTypeReference); - - return schemaDataResponseList; - - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Override - public void close() { - if (client != null) { - client.close(); - } - } -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index 3cdc53d..3c202e6 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -1,10 +1,13 @@ package nl.healthri.fdp.uploadschema; +import com.fasterxml.jackson.databind.ObjectMapper; +import nl.healthri.fdp.uploadschema.integration.FDP; import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.RdfUtils; +import nl.healthri.fdp.uploadschema.utils.XlsToRdfUtils; import org.eclipse.rdf4j.model.Model; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,9 +57,10 @@ public static void main(String... args) { public void run() { try { final Properties properties = Properties.load(propertyFile); - final FDP fdp = FDP.connectToFdp(hostname, username, password); + final FDP fdp = new FDP(hostname, username, password); final FileHandler fileHandler = new FileHandler(); + switch (command) { case TEMPLATE -> { convertTemplatesToShaclShapes(properties); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/LoginRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/LoginRequest.java new file mode 100644 index 0000000..1bedfc5 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/LoginRequest.java @@ -0,0 +1,5 @@ +package nl.healthri.fdp.uploadschema.dto.request; + +public record LoginRequest(String email, + String password) { +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/requestbodies/ReleaseSchemaParms.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/ReleaseSchemaRequest.java similarity index 54% rename from src/main/java/nl/healthri/fdp/uploadschema/requestbodies/ReleaseSchemaParms.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/request/ReleaseSchemaRequest.java index f366899..88c7bc2 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/requestbodies/ReleaseSchemaParms.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/ReleaseSchemaRequest.java @@ -1,10 +1,10 @@ -package nl.healthri.fdp.uploadschema.requestbodies; +package nl.healthri.fdp.uploadschema.dto.request; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import nl.healthri.fdp.uploadschema.Version; -public record ReleaseSchemaParms( +public record ReleaseSchemaRequest( @JsonProperty("description") String resourceName, boolean published, @@ -14,7 +14,7 @@ public record ReleaseSchemaParms( String patch) { @JsonIgnore - public static ReleaseSchemaParms of(String resourceName, boolean published, Version v) { - return new ReleaseSchemaParms(resourceName, published, v.toString(), "" + v.major(), "" + v.minor(), "" + v.patch()); + public static ReleaseSchemaRequest of(String resourceName, boolean published, Version v) { + return new ReleaseSchemaRequest(resourceName, published, v.toString(), "" + v.major(), "" + v.minor(), "" + v.patch()); } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/ResourceRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/ResourceRequest.java new file mode 100644 index 0000000..69d1fa8 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/ResourceRequest.java @@ -0,0 +1,17 @@ +package nl.healthri.fdp.uploadschema.dto.request; + +import java.util.ArrayList; + +public record ResourceRequest(String name, + String urlPrefix, + ArrayList metadataSchemaUuids, + ArrayList targetClassUris, + ArrayList children, + ArrayList externalLinks) { + + public record ResourceChild(String UUID) { + } + + public record ResourceLink(String title, String propertyUri) { + } +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/requestbodies/EditSchemaParms.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/UpdateSchemaRequest.java similarity index 74% rename from src/main/java/nl/healthri/fdp/uploadschema/requestbodies/EditSchemaParms.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/request/UpdateSchemaRequest.java index d7fa5e1..677ec7c 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/requestbodies/EditSchemaParms.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/UpdateSchemaRequest.java @@ -1,8 +1,8 @@ -package nl.healthri.fdp.uploadschema.requestbodies; +package nl.healthri.fdp.uploadschema.dto.request; import java.util.Set; -public record EditSchemaParms( +public record UpdateSchemaRequest( String name, String description, boolean abstractSchema, diff --git a/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/ResourceResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/ResourceResponse.java similarity index 93% rename from src/main/java/nl/healthri/fdp/uploadschema/requestresponses/ResourceResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/response/ResourceResponse.java index 92b0251..6364a69 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/ResourceResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/ResourceResponse.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.requestresponses; +package nl.healthri.fdp.uploadschema.dto.response; import java.util.ArrayList; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/SchemaDataResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/SchemaDataResponse.java similarity index 94% rename from src/main/java/nl/healthri/fdp/uploadschema/requestresponses/SchemaDataResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/response/SchemaDataResponse.java index ab2f6a9..e5bd94e 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/SchemaDataResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/SchemaDataResponse.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.requestresponses; +package nl.healthri.fdp.uploadschema.dto.response; import java.util.ArrayList; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/TokenResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/TokenResponse.java similarity index 69% rename from src/main/java/nl/healthri/fdp/uploadschema/requestresponses/TokenResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/response/TokenResponse.java index 5822266..8c13786 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/TokenResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/TokenResponse.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.requestresponses; +package nl.healthri.fdp.uploadschema.dto.response; public record TokenResponse(String token) { public String asHeaderString() { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/UpdateResourceResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/UpdateResourceResponse.java new file mode 100644 index 0000000..0fc574e --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/UpdateResourceResponse.java @@ -0,0 +1,21 @@ +package nl.healthri.fdp.uploadschema.dto.response; + +import nl.healthri.fdp.uploadschema.dto.request.ResourceRequest; + +import java.util.ArrayList; + +public record UpdateResourceResponse(String uuid, + String name, + String urlPrefix, + ArrayList metadataSchemaUuids, + ArrayList targetClassUris, + ArrayList children, + ArrayList externalLinks) { + + public record ResourceChild(String UUID) { + } + + public record ResourceLink(String title, String propertyUri) { + } + +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/SchemaEdit.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/UpdateSchemaResponse.java similarity index 77% rename from src/main/java/nl/healthri/fdp/uploadschema/requestresponses/SchemaEdit.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/response/UpdateSchemaResponse.java index 35de85d..644c4ce 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/SchemaEdit.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/UpdateSchemaResponse.java @@ -1,8 +1,8 @@ -package nl.healthri.fdp.uploadschema.requestresponses; +package nl.healthri.fdp.uploadschema.dto.response; import java.util.HashSet; -public record SchemaEdit( +public record UpdateSchemaResponse( String uuid, String name, String description, diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FDP.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FDP.java new file mode 100644 index 0000000..7047c4c --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FDP.java @@ -0,0 +1,386 @@ +package nl.healthri.fdp.uploadschema.integration; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import nl.healthri.fdp.uploadschema.dto.request.*; +import nl.healthri.fdp.uploadschema.dto.response.*; +import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; +import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; +import nl.healthri.fdp.uploadschema.utils.HttpRequestUtils; +import nl.healthri.fdp.uploadschema.utils.ResourceMap; +import nl.healthri.fdp.uploadschema.utils.ShapesMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpRequest.BodyPublisher; +import java.net.http.HttpResponse; +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.*; +import java.util.stream.Collectors; + +public class FDP { + private final HttpClient client; + private final String url; + private final String authToken; + private final ObjectMapper objectMapper; + + private static final Logger logger = LoggerFactory.getLogger(FDP.class); + + // TODO: parameters as objects for dependency injection and easy mocking + public FDP(URI url, String username, String password) { + this.objectMapper = new ObjectMapper(); + + this.client = HttpClient.newBuilder() + .followRedirects(HttpClient.Redirect.NORMAL) + .connectTimeout(Duration.of(30000, ChronoUnit.MILLIS)) + .build(); + if (this.client == null) { + throw new NullPointerException("HttpClient is null"); + } + + this.url = url.toString(); + if (this.url == null || this.url.isEmpty()) { + throw new IllegalArgumentException("URL is null or empty"); + } + + this.authToken = getAuthorizationToken(username, password); + if (this.authToken == null || this.authToken.isEmpty()) { + throw new IllegalArgumentException("AuthToken is null or empty"); + } + } + + public String getAuthorizationToken(String username, String password) { + logger.info("Connecting to FDP at {} as {} ", url, username); + + try { + URI uri = new URI(this.url + "/tokens"); + + // Creates DTO for LoginRequest + LoginRequest loginRequest = new LoginRequest(username, password); + + // Creates payload from LoginRequest DTO + BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(loginRequest) + ); + + HttpRequest request = HttpRequest.newBuilder() + .POST(requestBody) + .uri(uri) + .header("accept", "application/json") + .header("Content-Type", "application/json") + .build(); + + + // Sends request + HttpResponse response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Handle each response based on Fair Data Point (FDP) Swagger documentation. + HttpRequestUtils.handleResponseStatus(response); + + // Maps response body to object + TokenResponse tokenResponse = objectMapper.readValue(response.body(), TokenResponse.class); + + return tokenResponse.asHeaderString(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public ShapesMap fetchSchemas() { + logger.info("Fetching metadata schemas from FDP"); + + try { + URI uri = new URI(this.url + "/metadata-schemas"); + + HttpRequest request = HttpRequest.newBuilder() + .GET() + .uri(uri) + .header("accept", "application/json") + .header("Content-Type", "application/json") + .header("Authorization", this.authToken) + .build(); + + // Sends request created through the client + HttpResponse response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Handle each response based on Fair Data Point (FDP) Swagger documentation. + HttpRequestUtils.handleResponseStatus(response); + + // Maps response body to object + SchemaDataResponse[] schemaDataResponseList = objectMapper.readValue(response.body(), SchemaDataResponse[].class); + + return new ShapesMap(schemaDataResponseList); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public ResourceMap fetchResources() { + logger.info("Fetching resources from fdp"); + + try { + URI uri = new URI(this.url + "/resource-definitions"); + + HttpRequest request = HttpRequest.newBuilder() + .GET() + .uri(uri) + .header("accept", "application/json") + .header("Content-Type", "application/json") + .header("Authorization", this.authToken) + .build(); + + // Sends request + HttpResponse response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Handle each response based on Fair Data Point (FDP) Swagger documentation. + HttpRequestUtils.handleResponseStatus(response); + + // Map response to body + ResourceResponse[] resourceResponseList = objectMapper.readValue(response.body(), ResourceResponse[].class); + + return new ResourceMap(resourceResponseList); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public void insertResource(ResourceUpdateInsertTask task) { + logger.info("Inserting {} resources into FDP", task.resource); + + try { + URI uri = new URI(this.url + "/resource-definitions"); + + // Creates DTO for resourceRequest + ResourceRequest resourceRequest = new ResourceRequest( + task.resource, + task.url(), + new ArrayList<>(List.of(task.shapeUUUID)), + new ArrayList<>(), + new ArrayList<>(), + new ArrayList<>()); + + + // Creates payload from DTO + BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(resourceRequest) + ); + + // Creates request + HttpRequest request = HttpRequest.newBuilder() + .POST(requestBody) + .uri(uri) + .header("accept", "application/json") + .header("content-type", "application/json") + .header("authorization", this.authToken) + .build(); + + // Sends request + HttpResponse response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Handle each response based on Fair Data Point (FDP) Swagger documentation. + HttpRequestUtils.handleResponseStatus(response); + + // Maps response body to object + ResourceResponse resourceResponse = objectMapper.readValue(response.body(), ResourceResponse.class); + + task.UUID = resourceResponse.uuid(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public ResourceResponse fetchResource(String resourceId){ + logger.info("fetching resource {} from FDP", resourceId); + + try { + URI uri = new URI(this.url + "/resource-definitions/" + resourceId); + + HttpRequest request = HttpRequest.newBuilder() + .GET() + .uri(uri) + .header("accept", "application/json") + .header("Content-Type", "application/json") + .header("Authorization", this.authToken) + .build(); + + // Sends request + HttpResponse response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Handle each response based on Fair Data Point (FDP) Swagger documentation. + HttpRequestUtils.handleResponseStatus(response); + + // Maps response body to object + return objectMapper.readValue(response.body(), ResourceResponse.class); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + public void updateResource(ResourceUpdateInsertTask task) { + logger.info("updating resource {} in FDP", task.resource); + + try { + ResourceResponse resourceResponse = fetchResource(task.UUID); + + if (resourceResponse.children().stream().anyMatch(c -> c.resourceDefinitionUuid().equals(task.childUUuid))) { + logger.info("resource {} already has link to child {}", resourceResponse.name(), task.childName); + } else { + //FIXME TagsURI is hardcoded.. + ResourceResponse.ListView listView = new ResourceResponse.ListView(task.pluralName(), "http://www.w3.org/ns/dcat#themeTaxonomy", new ArrayList<>()); + ResourceResponse.Child child = new ResourceResponse.Child(task.childUUuid, task.childRelationIri, listView); + resourceResponse.children().add(child); + } + + URI uri = new URI(this.url + "/resource-definitions/" + task.UUID); + + BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(resourceResponse) + ); + + HttpRequest request = HttpRequest.newBuilder() + .PUT(requestBody) + .uri(uri) + .header("accept", "application/json") + .header("Content-Type", "application/json") + .header("Authorization", this.authToken) + .build(); + + // Sends request + HttpResponse response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Handle each response based on Fair Data Point (FDP) Swagger documentation. + HttpRequestUtils.handleResponseStatus(response); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * @param task task, with info about the shape to create, + * when the shapes are created it will update this parameter by setting the UUID! + */ + public void insertSchema(ShapeUpdateInsertTask task) { + logger.info("Inserting {} schema into FDP", task.shape); + + try { + URI uri = new URI(this.url + "/metadata-schemas"); + + UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( + task.shape, + task.description(), false, + task.model, + getParentUID(task.parents), + task.shape, + task.url()); + + BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(updateSchemaRequest) + ); + + HttpRequest request = HttpRequest.newBuilder() + .POST(requestBody) + .uri(uri) + .header("accept", "application/json") + .header("Content-Type", "application/json") + .header("Authorization", this.authToken) + .build(); + + // Sends request + HttpResponse response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Handle each response based on Fair Data Point (FDP) Swagger documentation. + HttpRequestUtils.handleResponseStatus(response); + + // Maps response body to object + ResourceResponse resourceResponse = objectMapper.readValue(response.body(), ResourceResponse.class); + + task.uuid = resourceResponse.uuid(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + + public void updateSchema(ShapeUpdateInsertTask task) { + logger.info("Updating shape {} in FDP", task.shape); + + try { + URI uri = new URI(this.url + "/metadata-schemas/" + task.uuid + "/draft"); + + UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( + task.shape, + task.description(), false, + task.model, + getParentUID(task.parents), + task.shape, + task.url()); + + BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(updateSchemaRequest) + ); + + HttpRequest request = HttpRequest.newBuilder() + .PUT(requestBody) + .uri(uri) + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .header("Authorization", this.authToken) + .build(); + + // Sends request + HttpResponse response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Handle each response based on Fair Data Point (FDP) Swagger documentation. + HttpRequestUtils.handleResponseStatus(response); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public void releaseSchema(ShapeUpdateInsertTask task) { + logger.info("Releasing {} into FDP", task.shape); + + try { + URI uri = new URI(this.url + "/metadata-schemas/" + task.uuid + "/versions"); + + ReleaseSchemaRequest releaseSchemaRequest = ReleaseSchemaRequest.of(task.shape, false, task.version); + BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(releaseSchemaRequest) + ); + + HttpRequest request = HttpRequest.newBuilder() + .POST(requestBody) + .uri(uri) + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .header("Authorization", this.authToken) + .build(); + + // Sends request + HttpResponse response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Handle each response based on Fair Data Point (FDP) Swagger documentation. + HttpRequestUtils.handleResponseStatus(response); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + + private Set getParentUID(Set shapes) { + if (shapes.isEmpty()) { + return Collections.emptySet(); + } + var shapesOnFdp = fetchSchemas(); + return shapes.stream() + .map(shapesOnFdp::getUUID).flatMap(Optional::stream) + .collect(Collectors.toSet()); + } +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/requestbodies/ResourceParms.java b/src/main/java/nl/healthri/fdp/uploadschema/requestbodies/ResourceParms.java deleted file mode 100644 index 1831df6..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/requestbodies/ResourceParms.java +++ /dev/null @@ -1,17 +0,0 @@ -package nl.healthri.fdp.uploadschema.requestbodies; - -import java.util.ArrayList; - -public record ResourceParms(String name, - String urlPrefix, - ArrayList metadataSchemaUuids, - ArrayList targetClassUris, - ArrayList children, - ArrayList externalLinks) { - - public record ResourceChild(String UUID) { - } - - public record ResourceLink(String title, String propertyUri) { - } -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/requestbodies/SchemaParms.java b/src/main/java/nl/healthri/fdp/uploadschema/requestbodies/SchemaParms.java deleted file mode 100644 index a525c92..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/requestbodies/SchemaParms.java +++ /dev/null @@ -1,7 +0,0 @@ -package nl.healthri.fdp.uploadschema.requestbodies; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public record SchemaParms(boolean drafts, - @JsonProperty("abstract") boolean abstractSchema) { -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/requestbodies/loginParms.java b/src/main/java/nl/healthri/fdp/uploadschema/requestbodies/loginParms.java deleted file mode 100644 index b420547..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/requestbodies/loginParms.java +++ /dev/null @@ -1,5 +0,0 @@ -package nl.healthri.fdp.uploadschema.requestbodies; - -public record loginParms(String email, - String password) { -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/FDPInfoResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/FDPInfoResponse.java deleted file mode 100644 index d6e3946..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/FDPInfoResponse.java +++ /dev/null @@ -1,10 +0,0 @@ -package nl.healthri.fdp.uploadschema.requestresponses; - -public record FDPInfoResponse(String name, String version, String builtAt) { - @Override - - public String toString() { - return name + " (" + version + ") build: " + builtAt; - } -} - diff --git a/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/ResourceEditResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/ResourceEditResponse.java deleted file mode 100644 index 4448054..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/requestresponses/ResourceEditResponse.java +++ /dev/null @@ -1,21 +0,0 @@ -package nl.healthri.fdp.uploadschema.requestresponses; - -import nl.healthri.fdp.uploadschema.requestbodies.ResourceParms; - -import java.util.ArrayList; - -public record ResourceEditResponse(String uuid, - String name, - String urlPrefix, - ArrayList metadataSchemaUuids, - ArrayList targetClassUris, - ArrayList children, - ArrayList externalLinks) { - - public record ResourceChild(String UUID) { - } - - public record ResourceLink(String title, String propertyUri) { - } - -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java index 934e617..cf1adff 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java @@ -1,6 +1,6 @@ package nl.healthri.fdp.uploadschema.tasks; -import nl.healthri.fdp.uploadschema.FDP; +import nl.healthri.fdp.uploadschema.integration.FDP; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.ResourceMap; import nl.healthri.fdp.uploadschema.utils.ShapesMap; @@ -27,7 +27,7 @@ public ResourceUpdateInsertTask(String resource) { } public static List createParentTask(Properties p, FDP fdp) { - var resourcesOnFdp = fdp.fetchResourceFromFDP(); + var resourcesOnFdp = fdp.fetchResources(); return p.resources.entrySet().stream().map(r -> { //now we to update the parent not the resource itself! @@ -41,8 +41,8 @@ public static List createParentTask(Properties p, FDP } public static List createTask(Properties p, FDP fdp) { - var resourcesOnFdp = fdp.fetchResourceFromFDP(); - var shapesOnFdp = fdp.fetchSchemaFromFDP(); + var resourcesOnFdp = fdp.fetchResources(); + var shapesOnFdp = fdp.fetchSchemas(); return p.resources.entrySet().stream().map(r -> new ResourceUpdateInsertTask(r.getKey()) .addExistingInfo(resourcesOnFdp) .addShapeUUID(shapesOnFdp, r.getValue().schema())).toList(); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java index e3f616e..d04d98c 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java @@ -1,6 +1,6 @@ package nl.healthri.fdp.uploadschema.tasks; -import nl.healthri.fdp.uploadschema.FDP; +import nl.healthri.fdp.uploadschema.integration.FDP; import nl.healthri.fdp.uploadschema.Version; import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; @@ -11,12 +11,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.net.URI; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; public class ShapeUpdateInsertTask { @@ -40,7 +36,7 @@ public ShapeUpdateInsertTask(String shape) { public static List createTasks(Properties p, FDP fdp, FileHandler fileHandler){ final List Shapes = p.schemasToPublish; final var files = p.getFiles(); - var shapesOnFdp = fdp.fetchSchemaFromFDP(); + var shapesOnFdp = fdp.fetchSchemas(); logger.info("found following shapes on fdp: {}", shapesOnFdp.keySet()); //list of the task we have to do for insert/updating shacls @@ -81,3 +77,4 @@ public ShapeStatus status() { return status; } } + diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/HttpRequestUtils.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/HttpRequestUtils.java new file mode 100644 index 0000000..a709446 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/HttpRequestUtils.java @@ -0,0 +1,27 @@ +package nl.healthri.fdp.uploadschema.utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpResponse; + + +public class HttpRequestUtils { + private static final Logger logger = LoggerFactory.getLogger(HttpRequestUtils.class); + + public static void handleResponseStatus(HttpResponse response) throws IOException { + String method = response.request().method(); + int statusCode = response.statusCode(); + URI uri = response.uri(); + + switch (statusCode) { + case 200 -> logger.info("[" + statusCode + "]" + " successfull request: " + method + " - " + uri); + case 400 -> throw new IllegalArgumentException("[" + statusCode + "]" + " bad request: " + method + " - " + uri); + case 401 -> throw new SecurityException("[" + statusCode + "]" + "Unauthorized: " + method + " - " + uri); + case 403 -> throw new SecurityException("[" + statusCode + "]" + "Forbidden: " + method + " - " + uri); + case 404 -> throw new IOException("[" + statusCode + "]" + "Resource Not Found: " + method + " - " + uri); + case 500 -> throw new IOException("[" + statusCode + "]" + "Internal Server Error: " + method + " - " + uri); + default -> throw new RuntimeException("[" + statusCode + "]" + "Unexpected HTTP status: " + method + " - " + uri); + } + } +} \ No newline at end of file diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/RequestBuilder.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/RequestBuilder.java deleted file mode 100644 index 9ae9425..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/RequestBuilder.java +++ /dev/null @@ -1,113 +0,0 @@ -package nl.healthri.fdp.uploadschema.utils; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import nl.healthri.fdp.uploadschema.requestresponses.TokenResponse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; - -public class RequestBuilder { - - private static final Logger logger = LoggerFactory.getLogger(RequestBuilder.class); - - private final ObjectMapper mapper; - private final HttpClient client; - - private String body = ""; - private String bearer = ""; - private URI uri = null; - - public RequestBuilder(ObjectMapper mapper, HttpClient client) { - this.mapper = mapper; - this.client = client; - } - - public RequestBuilder setUri(String uri) { - this.uri = URI.create(uri); - return this; - } - - public RequestBuilder setUri(String uri, Object parms) { - //FIXME, this is ugly - try { - String json = mapper.writeValueAsString(parms); - String p = "?" + json.substring(1, json.length() - 1) - .replaceAll(",", "&") - .replaceAll(":", "=") - .replaceAll("\"", ""); - this.uri = URI.create(uri + p); - } catch (JsonProcessingException e) { - logger.error(e.getMessage()); - throw new RuntimeException(e); - } - return this; - } - - - public RequestBuilder setBody(Object obj) { - try { - this.body = mapper.writeValueAsString(obj); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - return this; - } - - public RequestBuilder setToken(TokenResponse token) { - this.bearer = token == null ? "" : token.asHeaderString(); - return this; - } - - public T post(Class clazz) { - var b = HttpRequest.newBuilder(uri) - .POST(HttpRequest.BodyPublishers.ofString(body)); - return run(b, clazz); - } - - public T get(Class clazz) { - var b = HttpRequest.newBuilder(uri) - .GET(); - return run(b, clazz); - } - - public T put(Class clazz) { - - var b = HttpRequest.newBuilder(uri).PUT(HttpRequest.BodyPublishers.ofString(body)); - return run(b, clazz); - } - - private T run(HttpRequest.Builder builder, Class clazz) { - try { - - var b = builder - .header("accept", "application/json") - .header("Content-Type", "application/json"); - var request = !bearer.isBlank() ? - b.header("Authorization", bearer).build() - : b.build(); - - logger.debug("body: {}", body); - logger.debug("url: {}", uri.toString()); - logger.debug("request: {}", request); - - HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); - if ((response.statusCode() / 100) == 2) { - logger.debug("request success: {}", response.statusCode()); - return mapper.readValue(response.body(), clazz); - } - throw new RuntimeException("Invalid request: " + response.statusCode() + " -> " + response.body()); - } catch (IOException e) { - logger.error("url: {}", uri.toString()); - throw new RuntimeException(e); - } catch (InterruptedException e) { - Thread.currentThread().interrupt();// - } - return null; //you can't get here... - } -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceMap.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceMap.java index c3a9b24..c15720b 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceMap.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceMap.java @@ -1,6 +1,6 @@ package nl.healthri.fdp.uploadschema.utils; -import nl.healthri.fdp.uploadschema.requestresponses.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.response.ResourceResponse; import java.util.Arrays; import java.util.Optional; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java index 9e7e5eb..a297843 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java @@ -1,7 +1,7 @@ package nl.healthri.fdp.uploadschema.utils; import nl.healthri.fdp.uploadschema.Version; -import nl.healthri.fdp.uploadschema.requestresponses.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.response.SchemaDataResponse; import java.util.Arrays; import java.util.Optional; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/XlsToRdfUtils.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/XlsToRdfUtils.java similarity index 98% rename from src/main/java/nl/healthri/fdp/uploadschema/XlsToRdfUtils.java rename to src/main/java/nl/healthri/fdp/uploadschema/utils/XlsToRdfUtils.java index 214ef7c..0ce3dbc 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/XlsToRdfUtils.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/XlsToRdfUtils.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema; +package nl.healthri.fdp.uploadschema.utils; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Logger; diff --git a/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java b/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java index 27541fa..2d4bfe0 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java @@ -1,8 +1,8 @@ package nl.healthri.fdp.uploadschema.tasks; -import nl.healthri.fdp.uploadschema.FDP; +import nl.healthri.fdp.uploadschema.integration.FDP; import nl.healthri.fdp.uploadschema.Version; -import nl.healthri.fdp.uploadschema.requestresponses.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.response.SchemaDataResponse; import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.RdfUtils; @@ -43,7 +43,7 @@ void testCreateTasks_updated_shape() { createFdpResponse("TestShape", "", "1.0.0", "uuid")); FDP fdp = Mockito.mock(FDP.class); - Mockito.when(fdp.fetchSchemaFromFDP()).thenReturn(shapesOnFdp); + Mockito.when(fdp.fetchSchemas()).thenReturn(shapesOnFdp); // Mock FileHandler FileHandler fileHandler = Mockito.mock(FileHandler.class); @@ -84,7 +84,7 @@ void testCreateTasks_identical_shape() { createFdpResponse("TestShape", getShapeModel1(), "1.0.0", "uuid")); FDP fdp = Mockito.mock(FDP.class); - Mockito.when(fdp.fetchSchemaFromFDP()).thenReturn(shapesOnFdp); + Mockito.when(fdp.fetchSchemas()).thenReturn(shapesOnFdp); // Mock FileHandler FileHandler fileHandler = Mockito.mock(FileHandler.class); @@ -125,7 +125,7 @@ void testCreateTasks_new() { createFdpResponse("JustAnotherShape", "", "1.0.0", "uuid")); FDP fdp = Mockito.mock(FDP.class); - Mockito.when(fdp.fetchSchemaFromFDP()).thenReturn(shapesOnFdp); + Mockito.when(fdp.fetchSchemas()).thenReturn(shapesOnFdp); // Mock FileHandler FileHandler fileHandler = Mockito.mock(FileHandler.class); From 5954441410effe44c00b7e3ddfb2dca704f049de Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Tue, 28 Oct 2025 11:25:58 +0100 Subject: [PATCH 09/51] refactor: general improvements - Clear folder structure - Split FDP into FdpClient, FdpService and IFdpClient according to SOLID principles --- README.md | 2 +- .../fdp/uploadschema/SchemaTools.java | 52 ++++++++----- .../{ => Resource}/ResourceRequest.java | 2 +- .../{ => Schema}/ReleaseSchemaRequest.java | 2 +- .../{ => Schema}/UpdateSchemaRequest.java | 2 +- .../dto/request/{ => auth}/LoginRequest.java | 2 +- .../{ => Resource}/ResourceResponse.java | 2 +- .../UpdateResourceResponse.java | 4 +- .../{ => Schema}/SchemaDataResponse.java | 2 +- .../{ => Schema}/UpdateSchemaResponse.java | 2 +- .../dto/response/TokenResponse.java | 7 -- .../dto/response/auth/LoginResponse.java | 7 ++ .../integration/{FDP.java => FdpClient.java} | 78 ++++++++----------- .../uploadschema/integration/FdpService.java | 12 +++ .../uploadschema/integration/IFdpClient.java | 18 +++++ .../tasks/ResourceUpdateInsertTask.java | 12 +-- .../tasks/ShapeUpdateInsertTask.java | 6 +- .../uploadschema/utils/HttpRequestUtils.java | 14 ++-- .../fdp/uploadschema/utils/ResourceMap.java | 2 +- .../fdp/uploadschema/utils/ShapesMap.java | 2 +- .../tasks/ShapeUpdateInsertTaskTest.java | 22 +++--- 21 files changed, 142 insertions(+), 110 deletions(-) rename src/main/java/nl/healthri/fdp/uploadschema/dto/request/{ => Resource}/ResourceRequest.java (89%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/request/{ => Schema}/ReleaseSchemaRequest.java (91%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/request/{ => Schema}/UpdateSchemaRequest.java (83%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/request/{ => auth}/LoginRequest.java (62%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/response/{ => Resource}/ResourceResponse.java (92%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/response/{ => Resource}/UpdateResourceResponse.java (82%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/response/{ => Schema}/SchemaDataResponse.java (93%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/response/{ => Schema}/UpdateSchemaResponse.java (85%) delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/dto/response/TokenResponse.java create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/dto/response/auth/LoginResponse.java rename src/main/java/nl/healthri/fdp/uploadschema/integration/{FDP.java => FdpClient.java} (84%) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java diff --git a/README.md b/README.md index 460b300..a4e5427 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Run the tool with the required configuration file: -i path to Properties.yaml, you can use relative location (default is ./Properties.yaml) works if the property file is located at the some location as the jar file. --u fdp admin user (default: albert.einstein@example.com) +-u fdpClient admin user (default: albert.einstein@example.com) -p password (default: password) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index 3c202e6..ffeee5d 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -1,7 +1,7 @@ package nl.healthri.fdp.uploadschema; import com.fasterxml.jackson.databind.ObjectMapper; -import nl.healthri.fdp.uploadschema.integration.FDP; +import nl.healthri.fdp.uploadschema.integration.FdpClient; import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; import nl.healthri.fdp.uploadschema.utils.FileHandler; @@ -17,11 +17,14 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.net.http.HttpClient; import java.nio.file.Files; import java.nio.file.Path; +import java.time.Duration; import java.util.ArrayList; import static java.util.function.Predicate.not; +import static nl.healthri.fdp.uploadschema.integration.FdpClient.getAuthorizationToken; @CommandLine.Command(name = "SchemaTools utility that create FDP ready Shacls and upload them the the FDP.", mixinStandardHelpOptions = true, version = "SchemaTool v1.0") @@ -57,7 +60,18 @@ public static void main(String... args) { public void run() { try { final Properties properties = Properties.load(propertyFile); - final FDP fdp = new FDP(hostname, username, password); + + + // Create FDP client + HttpClient httpClient = HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(10)) + .build(); + + ObjectMapper objectMapper = new ObjectMapper(); + String authToken = FdpClient.getAuthorizationToken(httpClient, this.hostname, this.username, this.password, objectMapper); + + final FdpClient fdpClient = new FdpClient(httpClient, hostname, authToken, objectMapper); + final FileHandler fileHandler = new FileHandler(); @@ -69,11 +83,11 @@ public void run() { } case BOTH -> { // TODO: create Constructor with fdp dependency injector - createOrUpdateSchemas(fdp, properties, force, fileHandler); - addResourceDescriptions(fdp, properties); + createOrUpdateSchemas(fdpClient, properties, force, fileHandler); + addResourceDescriptions(fdpClient, properties); } - case SCHEMA -> createOrUpdateSchemas(fdp, properties, force, fileHandler); - case RESOURCE -> addResourceDescriptions(fdp, properties); + case SCHEMA -> createOrUpdateSchemas(fdpClient, properties, force, fileHandler); + case RESOURCE -> addResourceDescriptions(fdpClient, properties); } } catch (IOException io) { throw new RuntimeException(io); @@ -110,46 +124,46 @@ public void mergeShapesForValidation(Properties properties, FileHandler rdfUtils rdfUtils.safeModel(path, m); } - public void createOrUpdateSchemas(FDP fdp, Properties properties, boolean force, FileHandler fileHandler) throws IOException { + public void createOrUpdateSchemas(FdpClient fdpClient, Properties properties, boolean force, FileHandler fileHandler) throws IOException { logger.info("Creating/updating schemas from tasks to FDP"); - var shapeTasks = ShapeUpdateInsertTask.createTasks(properties, fdp, fileHandler); + var shapeTasks = ShapeUpdateInsertTask.createTasks(properties, fdpClient, fileHandler); shapeTasks.forEach(task -> { switch (task.status()) { case INSERT -> { - fdp.insertSchema(task); - fdp.releaseSchema(task); + fdpClient.insertSchema(task); + fdpClient.releaseSchema(task); } case SAME -> { if (force) { - fdp.updateSchema(task); - fdp.releaseSchema(task); + fdpClient.updateSchema(task); + fdpClient.releaseSchema(task); logger.info("Schema {} is updated, it was the same but force was set", task.shape); } else { logger.warn("Schema {} is not updated because it's still the same", task.shape); } } case UPDATE -> { - fdp.updateSchema(task); - fdp.releaseSchema(task); + fdpClient.updateSchema(task); + fdpClient.releaseSchema(task); } } }); } - public void addResourceDescriptions(FDP fdp, Properties properties) { + public void addResourceDescriptions(FdpClient fdpClient, Properties properties) { logger.info("Adding resource descriptions from resource tasks to FDP"); - var resourceTasks = ResourceUpdateInsertTask.createTask(properties, fdp); - resourceTasks.stream().filter(ResourceUpdateInsertTask::isInsert).forEach(fdp::insertResource); + var resourceTasks = ResourceUpdateInsertTask.createTask(properties, fdpClient); + resourceTasks.stream().filter(ResourceUpdateInsertTask::isInsert).forEach(fdpClient::insertResource); if (resourceTasks.stream().noneMatch(not(ResourceUpdateInsertTask::isInsert))) { logger.warn("Updating resources is not supported yet, but will try to add children if needed)"); } //add the previous resources as child to parent. - var resourceTasksParents = ResourceUpdateInsertTask.createParentTask(properties, fdp); - resourceTasksParents.stream().filter(ResourceUpdateInsertTask::hasChild).forEach(fdp::updateResource); + var resourceTasksParents = ResourceUpdateInsertTask.createParentTask(properties, fdpClient); + resourceTasksParents.stream().filter(ResourceUpdateInsertTask::hasChild).forEach(fdpClient::updateResource); } public enum CommandEnum { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/ResourceRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Resource/ResourceRequest.java similarity index 89% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/request/ResourceRequest.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/request/Resource/ResourceRequest.java index 69d1fa8..721a10c 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/ResourceRequest.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Resource/ResourceRequest.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.request; +package nl.healthri.fdp.uploadschema.dto.request.Resource; import java.util.ArrayList; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/ReleaseSchemaRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/ReleaseSchemaRequest.java similarity index 91% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/request/ReleaseSchemaRequest.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/ReleaseSchemaRequest.java index 88c7bc2..7fc25f0 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/ReleaseSchemaRequest.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/ReleaseSchemaRequest.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.request; +package nl.healthri.fdp.uploadschema.dto.request.Schema; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/UpdateSchemaRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/UpdateSchemaRequest.java similarity index 83% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/request/UpdateSchemaRequest.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/UpdateSchemaRequest.java index 677ec7c..e9ddf83 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/UpdateSchemaRequest.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/UpdateSchemaRequest.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.request; +package nl.healthri.fdp.uploadschema.dto.request.Schema; import java.util.Set; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/LoginRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/auth/LoginRequest.java similarity index 62% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/request/LoginRequest.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/request/auth/LoginRequest.java index 1bedfc5..562da9b 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/LoginRequest.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/auth/LoginRequest.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.request; +package nl.healthri.fdp.uploadschema.dto.request.auth; public record LoginRequest(String email, String password) { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/ResourceResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/ResourceResponse.java similarity index 92% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/response/ResourceResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/ResourceResponse.java index 6364a69..1a389b7 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/ResourceResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/ResourceResponse.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.response; +package nl.healthri.fdp.uploadschema.dto.response.Resource; import java.util.ArrayList; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/UpdateResourceResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/UpdateResourceResponse.java similarity index 82% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/response/UpdateResourceResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/UpdateResourceResponse.java index 0fc574e..fdffc1b 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/UpdateResourceResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/UpdateResourceResponse.java @@ -1,6 +1,6 @@ -package nl.healthri.fdp.uploadschema.dto.response; +package nl.healthri.fdp.uploadschema.dto.response.Resource; -import nl.healthri.fdp.uploadschema.dto.request.ResourceRequest; +import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; import java.util.ArrayList; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/SchemaDataResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Schema/SchemaDataResponse.java similarity index 93% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/response/SchemaDataResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/response/Schema/SchemaDataResponse.java index e5bd94e..b0f3136 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/SchemaDataResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Schema/SchemaDataResponse.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.response; +package nl.healthri.fdp.uploadschema.dto.response.Schema; import java.util.ArrayList; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/UpdateSchemaResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Schema/UpdateSchemaResponse.java similarity index 85% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/response/UpdateSchemaResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/response/Schema/UpdateSchemaResponse.java index 644c4ce..b4630fa 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/UpdateSchemaResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Schema/UpdateSchemaResponse.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.response; +package nl.healthri.fdp.uploadschema.dto.response.Schema; import java.util.HashSet; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/TokenResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/TokenResponse.java deleted file mode 100644 index 8c13786..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/TokenResponse.java +++ /dev/null @@ -1,7 +0,0 @@ -package nl.healthri.fdp.uploadschema.dto.response; - -public record TokenResponse(String token) { - public String asHeaderString() { - return "Bearer " + token; - } -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/auth/LoginResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/auth/LoginResponse.java new file mode 100644 index 0000000..58c83b1 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/auth/LoginResponse.java @@ -0,0 +1,7 @@ +package nl.healthri.fdp.uploadschema.dto.response.auth; + +public record LoginResponse(String token) { + public String asHeaderString() { + return "Bearer " + token; + } +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FDP.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java similarity index 84% rename from src/main/java/nl/healthri/fdp/uploadschema/integration/FDP.java rename to src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java index 7047c4c..e9e460e 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FDP.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java @@ -1,9 +1,13 @@ package nl.healthri.fdp.uploadschema.integration; -import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import nl.healthri.fdp.uploadschema.dto.request.*; -import nl.healthri.fdp.uploadschema.dto.response.*; +import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; +import nl.healthri.fdp.uploadschema.dto.request.Schema.ReleaseSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.request.Schema.UpdateSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; +import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; import nl.healthri.fdp.uploadschema.utils.HttpRequestUtils; @@ -12,60 +16,45 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.io.IOException; import java.net.URI; +import java.net.URL; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublisher; import java.net.http.HttpResponse; -import java.time.Duration; -import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; -public class FDP { +public class FdpClient implements IFdpClient { private final HttpClient client; - private final String url; + private final URI hostname; private final String authToken; private final ObjectMapper objectMapper; + private static final Logger logger = LoggerFactory.getLogger(FdpClient.class); - private static final Logger logger = LoggerFactory.getLogger(FDP.class); + public FdpClient(HttpClient client, URI hostname, String authToken, ObjectMapper objectMapper) { + this.client = Objects.requireNonNull(client, "HttpClient must not be null"); + this.hostname = Objects.requireNonNull(hostname, "URL must not be null"); + this.objectMapper = Objects.requireNonNull(objectMapper, "ObjectMapper must not be null"); - // TODO: parameters as objects for dependency injection and easy mocking - public FDP(URI url, String username, String password) { - this.objectMapper = new ObjectMapper(); - - this.client = HttpClient.newBuilder() - .followRedirects(HttpClient.Redirect.NORMAL) - .connectTimeout(Duration.of(30000, ChronoUnit.MILLIS)) - .build(); - if (this.client == null) { - throw new NullPointerException("HttpClient is null"); - } - - this.url = url.toString(); - if (this.url == null || this.url.isEmpty()) { - throw new IllegalArgumentException("URL is null or empty"); - } - - this.authToken = getAuthorizationToken(username, password); - if (this.authToken == null || this.authToken.isEmpty()) { - throw new IllegalArgumentException("AuthToken is null or empty"); + if (authToken == null || authToken.isBlank()) { + throw new IllegalArgumentException("authToken must not be null or empty"); } + this.authToken = authToken; } - public String getAuthorizationToken(String username, String password) { - logger.info("Connecting to FDP at {} as {} ", url, username); + public static String getAuthorizationToken(HttpClient client, URI hostname, String username, String password, ObjectMapper objectMapper) { + logger.info("Connecting to FDP at {} as {} ", hostname, username); try { - URI uri = new URI(this.url + "/tokens"); + URI uri = new URI(hostname + "/tokens"); // Creates DTO for LoginRequest LoginRequest loginRequest = new LoginRequest(username, password); // Creates payload from LoginRequest DTO BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( - this.objectMapper.writeValueAsString(loginRequest) + objectMapper.writeValueAsString(loginRequest) ); HttpRequest request = HttpRequest.newBuilder() @@ -77,15 +66,15 @@ public String getAuthorizationToken(String username, String password) { // Sends request - HttpResponse response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); + HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); // Maps response body to object - TokenResponse tokenResponse = objectMapper.readValue(response.body(), TokenResponse.class); + LoginResponse loginResponse = objectMapper.readValue(response.body(), LoginResponse.class); - return tokenResponse.asHeaderString(); + return loginResponse.asHeaderString(); } catch (Exception e) { throw new RuntimeException(e); } @@ -95,7 +84,7 @@ public ShapesMap fetchSchemas() { logger.info("Fetching metadata schemas from FDP"); try { - URI uri = new URI(this.url + "/metadata-schemas"); + URI uri = new URI(this.hostname + "/metadata-schemas"); HttpRequest request = HttpRequest.newBuilder() .GET() @@ -125,7 +114,7 @@ public ResourceMap fetchResources() { logger.info("Fetching resources from fdp"); try { - URI uri = new URI(this.url + "/resource-definitions"); + URI uri = new URI(this.hostname + "/resource-definitions"); HttpRequest request = HttpRequest.newBuilder() .GET() @@ -155,7 +144,7 @@ public void insertResource(ResourceUpdateInsertTask task) { logger.info("Inserting {} resources into FDP", task.resource); try { - URI uri = new URI(this.url + "/resource-definitions"); + URI uri = new URI(this.hostname + "/resource-definitions"); // Creates DTO for resourceRequest ResourceRequest resourceRequest = new ResourceRequest( @@ -200,7 +189,7 @@ public ResourceResponse fetchResource(String resourceId){ logger.info("fetching resource {} from FDP", resourceId); try { - URI uri = new URI(this.url + "/resource-definitions/" + resourceId); + URI uri = new URI(this.hostname + "/resource-definitions/" + resourceId); HttpRequest request = HttpRequest.newBuilder() .GET() @@ -237,7 +226,7 @@ public void updateResource(ResourceUpdateInsertTask task) { resourceResponse.children().add(child); } - URI uri = new URI(this.url + "/resource-definitions/" + task.UUID); + URI uri = new URI(this.hostname + "/resource-definitions/" + task.UUID); BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( this.objectMapper.writeValueAsString(resourceResponse) @@ -269,7 +258,7 @@ public void insertSchema(ShapeUpdateInsertTask task) { logger.info("Inserting {} schema into FDP", task.shape); try { - URI uri = new URI(this.url + "/metadata-schemas"); + URI uri = new URI(this.hostname + "/metadata-schemas"); UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( task.shape, @@ -311,7 +300,7 @@ public void updateSchema(ShapeUpdateInsertTask task) { logger.info("Updating shape {} in FDP", task.shape); try { - URI uri = new URI(this.url + "/metadata-schemas/" + task.uuid + "/draft"); + URI uri = new URI(this.hostname + "/metadata-schemas/" + task.uuid + "/draft"); UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( task.shape, @@ -347,7 +336,7 @@ public void releaseSchema(ShapeUpdateInsertTask task) { logger.info("Releasing {} into FDP", task.shape); try { - URI uri = new URI(this.url + "/metadata-schemas/" + task.uuid + "/versions"); + URI uri = new URI(this.hostname + "/metadata-schemas/" + task.uuid + "/versions"); ReleaseSchemaRequest releaseSchemaRequest = ReleaseSchemaRequest.of(task.shape, false, task.version); BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( @@ -373,7 +362,6 @@ public void releaseSchema(ShapeUpdateInsertTask task) { } } - private Set getParentUID(Set shapes) { if (shapes.isEmpty()) { return Collections.emptySet(); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java new file mode 100644 index 0000000..d196027 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java @@ -0,0 +1,12 @@ +package nl.healthri.fdp.uploadschema.integration; + +@Service +public class FdpService { + private final IFdpClient fdpClient; + + @Autowired + public FdpService(IFdpClient fdpClient) { + this.fdpClient = fdpClient; + } +} + diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java new file mode 100644 index 0000000..d176ffc --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java @@ -0,0 +1,18 @@ +package nl.healthri.fdp.uploadschema.integration; + +import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; +import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; +import nl.healthri.fdp.uploadschema.utils.ResourceMap; +import nl.healthri.fdp.uploadschema.utils.ShapesMap; +import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; + +public interface IFdpClient { + ShapesMap fetchSchemas(); + ResourceMap fetchResources(); + void insertResource(ResourceUpdateInsertTask task); + void updateResource(ResourceUpdateInsertTask task); + ResourceResponse fetchResource(String resourceId); + void insertSchema(ShapeUpdateInsertTask task); + void updateSchema(ShapeUpdateInsertTask task); + void releaseSchema(ShapeUpdateInsertTask task); +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java index cf1adff..c77a827 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java @@ -1,6 +1,6 @@ package nl.healthri.fdp.uploadschema.tasks; -import nl.healthri.fdp.uploadschema.integration.FDP; +import nl.healthri.fdp.uploadschema.integration.FdpClient; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.ResourceMap; import nl.healthri.fdp.uploadschema.utils.ShapesMap; @@ -26,8 +26,8 @@ public ResourceUpdateInsertTask(String resource) { this.resource = resource; } - public static List createParentTask(Properties p, FDP fdp) { - var resourcesOnFdp = fdp.fetchResources(); + public static List createParentTask(Properties p, FdpClient fdpClient) { + var resourcesOnFdp = fdpClient.fetchResources(); return p.resources.entrySet().stream().map(r -> { //now we to update the parent not the resource itself! @@ -40,9 +40,9 @@ public static List createParentTask(Properties p, FDP }).toList(); } - public static List createTask(Properties p, FDP fdp) { - var resourcesOnFdp = fdp.fetchResources(); - var shapesOnFdp = fdp.fetchSchemas(); + public static List createTask(Properties p, FdpClient fdpClient) { + var resourcesOnFdp = fdpClient.fetchResources(); + var shapesOnFdp = fdpClient.fetchSchemas(); return p.resources.entrySet().stream().map(r -> new ResourceUpdateInsertTask(r.getKey()) .addExistingInfo(resourcesOnFdp) .addShapeUUID(shapesOnFdp, r.getValue().schema())).toList(); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java index d04d98c..b2e462f 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java @@ -1,6 +1,6 @@ package nl.healthri.fdp.uploadschema.tasks; -import nl.healthri.fdp.uploadschema.integration.FDP; +import nl.healthri.fdp.uploadschema.integration.FdpClient; import nl.healthri.fdp.uploadschema.Version; import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; @@ -33,10 +33,10 @@ public ShapeUpdateInsertTask(String shape) { this.shape = shape; } - public static List createTasks(Properties p, FDP fdp, FileHandler fileHandler){ + public static List createTasks(Properties p, FdpClient fdpClient, FileHandler fileHandler){ final List Shapes = p.schemasToPublish; final var files = p.getFiles(); - var shapesOnFdp = fdp.fetchSchemas(); + var shapesOnFdp = fdpClient.fetchSchemas(); logger.info("found following shapes on fdp: {}", shapesOnFdp.keySet()); //list of the task we have to do for insert/updating shacls diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/HttpRequestUtils.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/HttpRequestUtils.java index a709446..58f91f7 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/HttpRequestUtils.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/HttpRequestUtils.java @@ -15,13 +15,13 @@ public static void handleResponseStatus(HttpResponse response) throws IO URI uri = response.uri(); switch (statusCode) { - case 200 -> logger.info("[" + statusCode + "]" + " successfull request: " + method + " - " + uri); - case 400 -> throw new IllegalArgumentException("[" + statusCode + "]" + " bad request: " + method + " - " + uri); - case 401 -> throw new SecurityException("[" + statusCode + "]" + "Unauthorized: " + method + " - " + uri); - case 403 -> throw new SecurityException("[" + statusCode + "]" + "Forbidden: " + method + " - " + uri); - case 404 -> throw new IOException("[" + statusCode + "]" + "Resource Not Found: " + method + " - " + uri); - case 500 -> throw new IOException("[" + statusCode + "]" + "Internal Server Error: " + method + " - " + uri); - default -> throw new RuntimeException("[" + statusCode + "]" + "Unexpected HTTP status: " + method + " - " + uri); + case 200 -> logger.info("[" + statusCode + "]" + " successfull request: " + method + " " + uri); + case 400 -> throw new IllegalArgumentException("[" + statusCode + "]" + " bad request: " + method + " " + uri); + case 401 -> throw new SecurityException("[" + statusCode + "]" + "Unauthorized: " + method + " " + uri); + case 403 -> throw new SecurityException("[" + statusCode + "]" + "Forbidden: " + method + " " + uri); + case 404 -> throw new IOException("[" + statusCode + "]" + "Resource Not Found: " + method + " " + uri); + case 500 -> throw new IOException("[" + statusCode + "]" + "Internal Server Error: " + method + " " + uri); + default -> throw new RuntimeException("[" + statusCode + "]" + "Unexpected HTTP status: " + method + " " + uri); } } } \ No newline at end of file diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceMap.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceMap.java index c15720b..8fd4509 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceMap.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceMap.java @@ -1,6 +1,6 @@ package nl.healthri.fdp.uploadschema.utils; -import nl.healthri.fdp.uploadschema.dto.response.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import java.util.Arrays; import java.util.Optional; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java index a297843..f9c8568 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java @@ -1,7 +1,7 @@ package nl.healthri.fdp.uploadschema.utils; import nl.healthri.fdp.uploadschema.Version; -import nl.healthri.fdp.uploadschema.dto.response.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import java.util.Arrays; import java.util.Optional; diff --git a/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java b/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java index 2d4bfe0..fd23ab1 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java @@ -1,8 +1,8 @@ package nl.healthri.fdp.uploadschema.tasks; -import nl.healthri.fdp.uploadschema.integration.FDP; +import nl.healthri.fdp.uploadschema.integration.FdpClient; import nl.healthri.fdp.uploadschema.Version; -import nl.healthri.fdp.uploadschema.dto.response.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.RdfUtils; @@ -42,15 +42,15 @@ void testCreateTasks_updated_shape() { ShapesMap shapesOnFdp = createFdpShapeMap( createFdpResponse("TestShape", "", "1.0.0", "uuid")); - FDP fdp = Mockito.mock(FDP.class); - Mockito.when(fdp.fetchSchemas()).thenReturn(shapesOnFdp); + FdpClient fdpClient = Mockito.mock(FdpClient.class); + Mockito.when(fdpClient.fetchSchemas()).thenReturn(shapesOnFdp); // Mock FileHandler FileHandler fileHandler = Mockito.mock(FileHandler.class); Mockito.when(fileHandler.readFiles(Mockito.anyList())).thenReturn(RdfUtils.fromTurtleString(getShapeModel2())); // Run createTasks - List tasks = ShapeUpdateInsertTask.createTasks(props, fdp, fileHandler); + List tasks = ShapeUpdateInsertTask.createTasks(props, fdpClient, fileHandler); // Assert assertEquals(1, tasks.size()); @@ -83,15 +83,15 @@ void testCreateTasks_identical_shape() { ShapesMap shapesOnFdp = createFdpShapeMap( createFdpResponse("TestShape", getShapeModel1(), "1.0.0", "uuid")); - FDP fdp = Mockito.mock(FDP.class); - Mockito.when(fdp.fetchSchemas()).thenReturn(shapesOnFdp); + FdpClient fdpClient = Mockito.mock(FdpClient.class); + Mockito.when(fdpClient.fetchSchemas()).thenReturn(shapesOnFdp); // Mock FileHandler FileHandler fileHandler = Mockito.mock(FileHandler.class); Mockito.when(fileHandler.readFiles(Mockito.anyList())).thenReturn(RdfUtils.fromTurtleString(getShapeModel1())); // Run createTasks - List tasks = ShapeUpdateInsertTask.createTasks(props, fdp, fileHandler); + List tasks = ShapeUpdateInsertTask.createTasks(props, fdpClient, fileHandler); // Assert assertEquals(1, tasks.size()); @@ -124,15 +124,15 @@ void testCreateTasks_new() { ShapesMap shapesOnFdp = createFdpShapeMap( createFdpResponse("JustAnotherShape", "", "1.0.0", "uuid")); - FDP fdp = Mockito.mock(FDP.class); - Mockito.when(fdp.fetchSchemas()).thenReturn(shapesOnFdp); + FdpClient fdpClient = Mockito.mock(FdpClient.class); + Mockito.when(fdpClient.fetchSchemas()).thenReturn(shapesOnFdp); // Mock FileHandler FileHandler fileHandler = Mockito.mock(FileHandler.class); Mockito.when(fileHandler.readFiles(Mockito.anyList())).thenReturn(RdfUtils.fromTurtleString(getShapeModel2())); // Run createTasks - List tasks = ShapeUpdateInsertTask.createTasks(props, fdp, fileHandler); + List tasks = ShapeUpdateInsertTask.createTasks(props, fdpClient, fileHandler); // Assert assertEquals(1, tasks.size()); From a0f0e6f23f422d06aa9cc2a4b5e6c458db4fdff2 Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Tue, 28 Oct 2025 13:23:26 +0100 Subject: [PATCH 10/51] feature: added spring-boot-starter for enabling dependency injection --- pom.xml | 6 ++++++ .../nl/healthri/fdp/uploadschema/integration/FdpClient.java | 2 ++ .../healthri/fdp/uploadschema/integration/FdpService.java | 3 +++ 3 files changed, 11 insertions(+) diff --git a/pom.xml b/pom.xml index a0fde61..b2dac9d 100644 --- a/pom.xml +++ b/pom.xml @@ -140,6 +140,12 @@ 5.20.0 test + + + org.springframework.boot + spring-boot-starter + 3.5.0 + diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java index e9e460e..4e88b1b 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java @@ -15,6 +15,7 @@ import nl.healthri.fdp.uploadschema.utils.ShapesMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; import java.net.URI; import java.net.URL; @@ -25,6 +26,7 @@ import java.util.*; import java.util.stream.Collectors; +@Component public class FdpClient implements IFdpClient { private final HttpClient client; private final URI hostname; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java index d196027..0e30e15 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java @@ -1,5 +1,8 @@ package nl.healthri.fdp.uploadschema.integration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + @Service public class FdpService { private final IFdpClient fdpClient; From e7f2cf0a04e81a839ec1a48588b39d17a97469d6 Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Wed, 29 Oct 2025 10:52:44 +0100 Subject: [PATCH 11/51] Refactor: added interface for FdpClient and seperated business logic from client to service --- .../uploadschema/integration/FdpClient.java | 197 ++++++------------ .../uploadschema/integration/FdpService.java | 128 +++++++++++- .../uploadschema/integration/IFdpClient.java | 21 +- .../tasks/ShapeUpdateInsertTask.java | 12 ++ 4 files changed, 211 insertions(+), 147 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java index 4e88b1b..b449141 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java @@ -1,9 +1,7 @@ package nl.healthri.fdp.uploadschema.integration; import com.fasterxml.jackson.databind.ObjectMapper; -import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; -import nl.healthri.fdp.uploadschema.dto.request.Schema.ReleaseSchemaRequest; -import nl.healthri.fdp.uploadschema.dto.request.Schema.UpdateSchemaRequest; + import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; @@ -11,14 +9,12 @@ import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; import nl.healthri.fdp.uploadschema.utils.HttpRequestUtils; -import nl.healthri.fdp.uploadschema.utils.ResourceMap; -import nl.healthri.fdp.uploadschema.utils.ShapesMap; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.net.URI; -import java.net.URL; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublisher; @@ -26,6 +22,11 @@ import java.util.*; import java.util.stream.Collectors; + +// TODO: Throw client exception instead of Runtimeexception (otherwise you hide the error encountered) +// TODO: Split Fdp Client and Service into FdpSchemaClient, FdpResourceClient, etc. +// TODO: + @Component public class FdpClient implements IFdpClient { private final HttpClient client; @@ -82,7 +83,7 @@ public static String getAuthorizationToken(HttpClient client, URI hostname, Stri } } - public ShapesMap fetchSchemas() { + public SchemaDataResponse[] fetchSchemas() { logger.info("Fetching metadata schemas from FDP"); try { @@ -103,23 +104,24 @@ public ShapesMap fetchSchemas() { HttpRequestUtils.handleResponseStatus(response); // Maps response body to object - SchemaDataResponse[] schemaDataResponseList = objectMapper.readValue(response.body(), SchemaDataResponse[].class); - - return new ShapesMap(schemaDataResponseList); - + return objectMapper.readValue(response.body(), SchemaDataResponse[].class); } catch (Exception e) { throw new RuntimeException(e); } } - public ResourceMap fetchResources() { - logger.info("Fetching resources from fdp"); + /** + * @param task task, with info about the shape to create, + * when the shapes are created it will update this parameter by setting the UUID! + */ + public ResourceResponse insertSchema(ShapeUpdateInsertTask task, BodyPublisher body) { + logger.info("Inserting {} schema into FDP", task.shape); try { - URI uri = new URI(this.hostname + "/resource-definitions"); + URI uri = new URI(this.hostname + "/metadata-schemas"); HttpRequest request = HttpRequest.newBuilder() - .GET() + .POST(body) .uri(uri) .header("accept", "application/json") .header("Content-Type", "application/json") @@ -132,44 +134,28 @@ public ResourceMap fetchResources() { // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); - // Map response to body - ResourceResponse[] resourceResponseList = objectMapper.readValue(response.body(), ResourceResponse[].class); - - return new ResourceMap(resourceResponseList); - + // Maps response body to object + return objectMapper.readValue(response.body(), ResourceResponse.class); } catch (Exception e) { throw new RuntimeException(e); } } - public void insertResource(ResourceUpdateInsertTask task) { - logger.info("Inserting {} resources into FDP", task.resource); - try { - URI uri = new URI(this.hostname + "/resource-definitions"); - // Creates DTO for resourceRequest - ResourceRequest resourceRequest = new ResourceRequest( - task.resource, - task.url(), - new ArrayList<>(List.of(task.shapeUUUID)), - new ArrayList<>(), - new ArrayList<>(), - new ArrayList<>()); + public void updateSchema(ShapeUpdateInsertTask task, BodyPublisher body) { + logger.info("Updating shape {} in FDP", task.shape); - // Creates payload from DTO - BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( - this.objectMapper.writeValueAsString(resourceRequest) - ); + try { + URI uri = new URI(this.hostname + "/metadata-schemas/" + task.uuid + "/draft"); - // Creates request HttpRequest request = HttpRequest.newBuilder() - .POST(requestBody) + .PUT(body) .uri(uri) - .header("accept", "application/json") - .header("content-type", "application/json") - .header("authorization", this.authToken) + .header("Accept", "application/json") + .header("Content-Type", "application/json") + .header("Authorization", this.authToken) .build(); // Sends request @@ -177,26 +163,21 @@ public void insertResource(ResourceUpdateInsertTask task) { // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); - - // Maps response body to object - ResourceResponse resourceResponse = objectMapper.readValue(response.body(), ResourceResponse.class); - - task.UUID = resourceResponse.uuid(); } catch (Exception e) { throw new RuntimeException(e); } } - public ResourceResponse fetchResource(String resourceId){ - logger.info("fetching resource {} from FDP", resourceId); + public void releaseSchema(ShapeUpdateInsertTask task, BodyPublisher body) { + logger.info("Releasing {} into FDP", task.shape); try { - URI uri = new URI(this.hostname + "/resource-definitions/" + resourceId); + URI uri = new URI(this.hostname + "/metadata-schemas/" + task.uuid + "/versions"); HttpRequest request = HttpRequest.newBuilder() - .GET() + .POST(body) .uri(uri) - .header("accept", "application/json") + .header("Accept", "application/json") .header("Content-Type", "application/json") .header("Authorization", this.authToken) .build(); @@ -207,35 +188,19 @@ public ResourceResponse fetchResource(String resourceId){ // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); - // Maps response body to object - return objectMapper.readValue(response.body(), ResourceResponse.class); } catch (Exception e) { throw new RuntimeException(e); } } - public void updateResource(ResourceUpdateInsertTask task) { - logger.info("updating resource {} in FDP", task.resource); - - try { - ResourceResponse resourceResponse = fetchResource(task.UUID); - - if (resourceResponse.children().stream().anyMatch(c -> c.resourceDefinitionUuid().equals(task.childUUuid))) { - logger.info("resource {} already has link to child {}", resourceResponse.name(), task.childName); - } else { - //FIXME TagsURI is hardcoded.. - ResourceResponse.ListView listView = new ResourceResponse.ListView(task.pluralName(), "http://www.w3.org/ns/dcat#themeTaxonomy", new ArrayList<>()); - ResourceResponse.Child child = new ResourceResponse.Child(task.childUUuid, task.childRelationIri, listView); - resourceResponse.children().add(child); - } - URI uri = new URI(this.hostname + "/resource-definitions/" + task.UUID); + public ResourceResponse[] fetchResources() { + logger.info("Fetching resources from fdp"); - BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( - this.objectMapper.writeValueAsString(resourceResponse) - ); + try { + URI uri = new URI(this.hostname + "/resource-definitions"); HttpRequest request = HttpRequest.newBuilder() - .PUT(requestBody) + .GET() .uri(uri) .header("accept", "application/json") .header("Content-Type", "application/json") @@ -247,35 +212,22 @@ public void updateResource(ResourceUpdateInsertTask task) { // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); + + // Map response to body + return objectMapper.readValue(response.body(), ResourceResponse[].class); } catch (Exception e) { throw new RuntimeException(e); } } - /** - * @param task task, with info about the shape to create, - * when the shapes are created it will update this parameter by setting the UUID! - */ - public void insertSchema(ShapeUpdateInsertTask task) { - logger.info("Inserting {} schema into FDP", task.shape); + public ResourceResponse fetchResource(String resourceId){ + logger.info("fetching resource {} from FDP", resourceId); try { - URI uri = new URI(this.hostname + "/metadata-schemas"); - - UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( - task.shape, - task.description(), false, - task.model, - getParentUID(task.parents), - task.shape, - task.url()); - - BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( - this.objectMapper.writeValueAsString(updateSchemaRequest) - ); + URI uri = new URI(this.hostname + "/resource-definitions/" + resourceId); HttpRequest request = HttpRequest.newBuilder() - .POST(requestBody) + .GET() .uri(uri) .header("accept", "application/json") .header("Content-Type", "application/json") @@ -289,39 +241,25 @@ public void insertSchema(ShapeUpdateInsertTask task) { HttpRequestUtils.handleResponseStatus(response); // Maps response body to object - ResourceResponse resourceResponse = objectMapper.readValue(response.body(), ResourceResponse.class); - - task.uuid = resourceResponse.uuid(); + return objectMapper.readValue(response.body(), ResourceResponse.class); } catch (Exception e) { throw new RuntimeException(e); } } - - public void updateSchema(ShapeUpdateInsertTask task) { - logger.info("Updating shape {} in FDP", task.shape); + public ResourceResponse insertResource(ResourceUpdateInsertTask task, BodyPublisher body) { + logger.info("Inserting {} resources into FDP", task.resource); try { - URI uri = new URI(this.hostname + "/metadata-schemas/" + task.uuid + "/draft"); - - UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( - task.shape, - task.description(), false, - task.model, - getParentUID(task.parents), - task.shape, - task.url()); - - BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( - this.objectMapper.writeValueAsString(updateSchemaRequest) - ); + URI uri = new URI(this.hostname + "/resource-definitions"); + // Creates request HttpRequest request = HttpRequest.newBuilder() - .PUT(requestBody) + .POST(body) .uri(uri) - .header("Accept", "application/json") - .header("Content-Type", "application/json") - .header("Authorization", this.authToken) + .header("accept", "application/json") + .header("content-type", "application/json") + .header("authorization", this.authToken) .build(); // Sends request @@ -329,26 +267,24 @@ public void updateSchema(ShapeUpdateInsertTask task) { // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); + + // Maps response body to object + return objectMapper.readValue(response.body(), ResourceResponse.class); } catch (Exception e) { throw new RuntimeException(e); } } - public void releaseSchema(ShapeUpdateInsertTask task) { - logger.info("Releasing {} into FDP", task.shape); + public void updateResource(ResourceUpdateInsertTask task, HttpRequest.BodyPublisher body) { + logger.info("updating resource {} in FDP", task.resource); try { - URI uri = new URI(this.hostname + "/metadata-schemas/" + task.uuid + "/versions"); - - ReleaseSchemaRequest releaseSchemaRequest = ReleaseSchemaRequest.of(task.shape, false, task.version); - BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( - this.objectMapper.writeValueAsString(releaseSchemaRequest) - ); + URI uri = new URI(this.hostname + "/resource-definitions/" + task.UUID); HttpRequest request = HttpRequest.newBuilder() - .POST(requestBody) + .PUT(body) .uri(uri) - .header("Accept", "application/json") + .header("accept", "application/json") .header("Content-Type", "application/json") .header("Authorization", this.authToken) .build(); @@ -358,19 +294,8 @@ public void releaseSchema(ShapeUpdateInsertTask task) { // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); - } catch (Exception e) { throw new RuntimeException(e); } } - - private Set getParentUID(Set shapes) { - if (shapes.isEmpty()) { - return Collections.emptySet(); - } - var shapesOnFdp = fetchSchemas(); - return shapes.stream() - .map(shapesOnFdp::getUUID).flatMap(Optional::stream) - .collect(Collectors.toSet()); - } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java index 0e30e15..b74a162 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java @@ -1,15 +1,139 @@ package nl.healthri.fdp.uploadschema.integration; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; +import nl.healthri.fdp.uploadschema.dto.request.Schema.ReleaseSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.request.Schema.UpdateSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; +import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; +import nl.healthri.fdp.uploadschema.utils.ResourceMap; +import nl.healthri.fdp.uploadschema.utils.ShapesMap; +import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.net.http.HttpRequest; +import java.util.*; +import java.util.stream.Collectors; + +import static nl.healthri.fdp.uploadschema.integration.FdpClient.getAuthorizationToken; + @Service public class FdpService { private final IFdpClient fdpClient; + private ObjectMapper objectMapper; + private static final Logger logger = LoggerFactory.getLogger(FdpService.class); @Autowired - public FdpService(IFdpClient fdpClient) { + public FdpService(IFdpClient fdpClient, ObjectMapper objectMapper) { this.fdpClient = fdpClient; + this.objectMapper = objectMapper; } -} + public static String GetAuthorizationToken(){ + + } + + public ShapesMap getAllSchemas() { + SchemaDataResponse[] schemaDataResponseList = fdpClient.fetchSchemas(); + return new ShapesMap(schemaDataResponseList); + } + + public void createSchema(ShapeUpdateInsertTask task) throws JsonProcessingException { + ShapesMap shapesMap = getAllSchemas(); + + UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( + task.shape, + task.description(), false, + task.model, + task.getParentUID(shapesMap), + task.shape, + task.url()); + + HttpRequest.BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(updateSchemaRequest) + ); + + ResourceResponse resourceResponse = fdpClient.insertSchema(task, requestBody); + task.uuid = resourceResponse.uuid(); + } + + + public void updateSchema(ShapeUpdateInsertTask task) throws JsonProcessingException { + ShapesMap shapesMap = getAllSchemas(); + + UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( + task.shape, + task.description(), false, + task.model, + task.getParentUID(shapesMap), + task.shape, + task.url()); + + HttpRequest.BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(updateSchemaRequest) + ); + + fdpClient.updateSchema(task, requestBody); + } + + public void releaseSchema(ShapeUpdateInsertTask task) throws JsonProcessingException { + ReleaseSchemaRequest releaseSchemaRequest = ReleaseSchemaRequest.of(task.shape, false, task.version); + HttpRequest.BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(releaseSchemaRequest) + ); + + fdpClient.releaseSchema(task, requestBody); + } + + public ResourceMap getAllResources() { + ResourceResponse[] resourceResponseList = fdpClient.fetchResources(); + return new ResourceMap(resourceResponseList); + } + + public ResourceResponse getResourceById(String resourceId) { + return fdpClient.fetchResource(resourceId); + } + + public void createResource(ResourceUpdateInsertTask task) throws JsonProcessingException { + ResourceRequest resourceRequest = new ResourceRequest( + task.resource, + task.url(), + new ArrayList<>(List.of(task.shapeUUUID)), + new ArrayList<>(), + new ArrayList<>(), + new ArrayList<>()); + + + // Creates payload from DTO + HttpRequest.BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(resourceRequest) + ); + + ResourceResponse resourceResponse = fdpClient.insertResource(task, requestBody); + task.UUID = resourceResponse.uuid(); + } + + public void updateResource(ResourceUpdateInsertTask task) throws JsonProcessingException { + ResourceResponse resourceResponse = fdpClient.fetchResource(task.UUID); + + if (resourceResponse.children().stream().anyMatch(c -> c.resourceDefinitionUuid().equals(task.childUUuid))) { + logger.info("resource {} already has link to child {}", resourceResponse.name(), task.childName); + } else { + //FIXME TagsURI is hardcoded.. + ResourceResponse.ListView listView = new ResourceResponse.ListView(task.pluralName(), "http://www.w3.org/ns/dcat#themeTaxonomy", new ArrayList<>()); + ResourceResponse.Child child = new ResourceResponse.Child(task.childUUuid, task.childRelationIri, listView); + resourceResponse.children().add(child); + } + + HttpRequest.BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(resourceResponse) + ); + + fdpClient.updateResource(task, requestBody); + } +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java index d176ffc..ece835a 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java @@ -1,18 +1,21 @@ package nl.healthri.fdp.uploadschema.integration; +import jakarta.annotation.Resource; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; -import nl.healthri.fdp.uploadschema.utils.ResourceMap; -import nl.healthri.fdp.uploadschema.utils.ShapesMap; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; +import java.net.http.HttpRequest; + public interface IFdpClient { - ShapesMap fetchSchemas(); - ResourceMap fetchResources(); - void insertResource(ResourceUpdateInsertTask task); - void updateResource(ResourceUpdateInsertTask task); + SchemaDataResponse[] fetchSchemas(); + ResourceResponse insertSchema(ShapeUpdateInsertTask task, HttpRequest.BodyPublisher body); + void updateSchema(ShapeUpdateInsertTask task, HttpRequest.BodyPublisher body); + void releaseSchema(ShapeUpdateInsertTask task, HttpRequest.BodyPublisher body); + + ResourceResponse[] fetchResources(); ResourceResponse fetchResource(String resourceId); - void insertSchema(ShapeUpdateInsertTask task); - void updateSchema(ShapeUpdateInsertTask task); - void releaseSchema(ShapeUpdateInsertTask task); + ResourceResponse insertResource(ResourceUpdateInsertTask task, HttpRequest.BodyPublisher body ); + void updateResource(ResourceUpdateInsertTask task, HttpRequest.BodyPublisher body); } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java index b2e462f..36539b8 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java @@ -1,10 +1,12 @@ package nl.healthri.fdp.uploadschema.tasks; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.integration.FdpClient; import nl.healthri.fdp.uploadschema.Version; import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.RdfUtils; +import nl.healthri.fdp.uploadschema.utils.ShapesMap; import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.model.impl.LinkedHashModel; import org.eclipse.rdf4j.model.util.Models; @@ -65,6 +67,16 @@ public static List createTasks(Properties p, FdpClient fd }).toList(); } + public Set getParentUID(ShapesMap shapesMap) { + if (this.parents.isEmpty()) { + return Collections.emptySet(); + } + + return this.parents.stream() + .map(shapesMap::getUUID).flatMap(Optional::stream) + .collect(Collectors.toSet()); + } + public String description() { return shape; } From 6465486e1371584782184364d7a8a35553d662e1 Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Wed, 29 Oct 2025 13:58:45 +0100 Subject: [PATCH 12/51] Refactor: Moved request body generator from DTO to Client and added authentication --- .../fdp/uploadschema/SchemaTools.java | 10 ++- .../uploadschema/integration/FdpClient.java | 89 ++++++++++++++----- .../uploadschema/integration/FdpService.java | 55 ++++-------- .../uploadschema/integration/IFdpClient.java | 19 ++-- 4 files changed, 103 insertions(+), 70 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index ffeee5d..a88b3dd 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -1,6 +1,7 @@ package nl.healthri.fdp.uploadschema; import com.fasterxml.jackson.databind.ObjectMapper; +import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; import nl.healthri.fdp.uploadschema.integration.FdpClient; import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; @@ -63,12 +64,16 @@ public void run() { // Create FDP client - HttpClient httpClient = HttpClient.newBuilder() + HttpClient client = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(10)) .build(); ObjectMapper objectMapper = new ObjectMapper(); - String authToken = FdpClient.getAuthorizationToken(httpClient, this.hostname, this.username, this.password, objectMapper); + LoginRequest loginRequest = new LoginRequest(this.username, this.password); + + FdpClient fdpClient = new FdpClient(client, this.hostname, objectMapper); + fdpClient.authenticate(loginRequest); + String authToken = FdpClient.getAuthToken(httpClient, this.hostname, this.username, this.password, objectMapper); final FdpClient fdpClient = new FdpClient(httpClient, hostname, authToken, objectMapper); @@ -82,7 +87,6 @@ public void run() { mergeShapesForValidation(properties, fileHandler); } case BOTH -> { - // TODO: create Constructor with fdp dependency injector createOrUpdateSchemas(fdpClient, properties, force, fileHandler); addResourceDescriptions(fdpClient, properties); } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java index b449141..4dd3f3d 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java @@ -2,6 +2,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; +import nl.healthri.fdp.uploadschema.dto.request.Schema.ReleaseSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.request.Schema.UpdateSchemaRequest; import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; @@ -10,6 +13,7 @@ import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; import nl.healthri.fdp.uploadschema.utils.HttpRequestUtils; +import org.eclipse.rdf4j.query.Update; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -20,7 +24,6 @@ import java.net.http.HttpRequest.BodyPublisher; import java.net.http.HttpResponse; import java.util.*; -import java.util.stream.Collectors; // TODO: Throw client exception instead of Runtimeexception (otherwise you hide the error encountered) @@ -31,37 +34,39 @@ public class FdpClient implements IFdpClient { private final HttpClient client; private final URI hostname; - private final String authToken; private final ObjectMapper objectMapper; + private String authToken; + private static final Logger logger = LoggerFactory.getLogger(FdpClient.class); - public FdpClient(HttpClient client, URI hostname, String authToken, ObjectMapper objectMapper) { + public FdpClient(HttpClient client, URI hostname, ObjectMapper objectMapper) { this.client = Objects.requireNonNull(client, "HttpClient must not be null"); this.hostname = Objects.requireNonNull(hostname, "URL must not be null"); this.objectMapper = Objects.requireNonNull(objectMapper, "ObjectMapper must not be null"); + } + + public void setAuthToken(LoginResponse loginResponse) { + this.authToken = loginResponse.asHeaderString(); + } - if (authToken == null || authToken.isBlank()) { - throw new IllegalArgumentException("authToken must not be null or empty"); + private void isAuthenticated() { + if (this.authToken == null || this.authToken.isBlank()) { + throw new IllegalStateException("FdpClient is not authenticated, authorization token is null or empty."); } - this.authToken = authToken; } - public static String getAuthorizationToken(HttpClient client, URI hostname, String username, String password, ObjectMapper objectMapper) { - logger.info("Connecting to FDP at {} as {} ", hostname, username); + public LoginResponse getAuthToken(LoginRequest loginRequest) { + logger.info("Connecting to FDP at {} as {} ", hostname, loginRequest.email()); try { - URI uri = new URI(hostname + "/tokens"); + URI uri = new URI(this.hostname + "/tokens"); - // Creates DTO for LoginRequest - LoginRequest loginRequest = new LoginRequest(username, password); - - // Creates payload from LoginRequest DTO - BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( - objectMapper.writeValueAsString(loginRequest) + HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(loginRequest) ); HttpRequest request = HttpRequest.newBuilder() - .POST(requestBody) + .POST(body) .uri(uri) .header("accept", "application/json") .header("Content-Type", "application/json") @@ -69,15 +74,14 @@ public static String getAuthorizationToken(HttpClient client, URI hostname, Stri // Sends request - HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); + HttpResponse response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); // Maps response body to object - LoginResponse loginResponse = objectMapper.readValue(response.body(), LoginResponse.class); + return this.objectMapper.readValue(response.body(), LoginResponse.class); - return loginResponse.asHeaderString(); } catch (Exception e) { throw new RuntimeException(e); } @@ -87,6 +91,8 @@ public SchemaDataResponse[] fetchSchemas() { logger.info("Fetching metadata schemas from FDP"); try { + isAuthenticated(); + URI uri = new URI(this.hostname + "/metadata-schemas"); HttpRequest request = HttpRequest.newBuilder() @@ -114,12 +120,18 @@ public SchemaDataResponse[] fetchSchemas() { * @param task task, with info about the shape to create, * when the shapes are created it will update this parameter by setting the UUID! */ - public ResourceResponse insertSchema(ShapeUpdateInsertTask task, BodyPublisher body) { + public ResourceResponse insertSchema(ShapeUpdateInsertTask task, UpdateSchemaRequest updateSchemaRequest) { logger.info("Inserting {} schema into FDP", task.shape); try { + isAuthenticated(); + URI uri = new URI(this.hostname + "/metadata-schemas"); + HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(updateSchemaRequest) + ); + HttpRequest request = HttpRequest.newBuilder() .POST(body) .uri(uri) @@ -144,12 +156,18 @@ public ResourceResponse insertSchema(ShapeUpdateInsertTask task, BodyPublisher b - public void updateSchema(ShapeUpdateInsertTask task, BodyPublisher body) { + public void updateSchema(ShapeUpdateInsertTask task, UpdateSchemaRequest updateSchemaRequest) { logger.info("Updating shape {} in FDP", task.shape); try { + isAuthenticated(); + URI uri = new URI(this.hostname + "/metadata-schemas/" + task.uuid + "/draft"); + HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(updateSchemaRequest) + ); + HttpRequest request = HttpRequest.newBuilder() .PUT(body) .uri(uri) @@ -168,12 +186,18 @@ public void updateSchema(ShapeUpdateInsertTask task, BodyPublisher body) { } } - public void releaseSchema(ShapeUpdateInsertTask task, BodyPublisher body) { + public void releaseSchema(ShapeUpdateInsertTask task, ReleaseSchemaRequest releaseSchemaRequest) { logger.info("Releasing {} into FDP", task.shape); try { + isAuthenticated(); + URI uri = new URI(this.hostname + "/metadata-schemas/" + task.uuid + "/versions"); + HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(releaseSchemaRequest) + ); + HttpRequest request = HttpRequest.newBuilder() .POST(body) .uri(uri) @@ -197,6 +221,8 @@ public ResourceResponse[] fetchResources() { logger.info("Fetching resources from fdp"); try { + isAuthenticated(); + URI uri = new URI(this.hostname + "/resource-definitions"); HttpRequest request = HttpRequest.newBuilder() @@ -224,6 +250,8 @@ public ResourceResponse fetchResource(String resourceId){ logger.info("fetching resource {} from FDP", resourceId); try { + isAuthenticated(); + URI uri = new URI(this.hostname + "/resource-definitions/" + resourceId); HttpRequest request = HttpRequest.newBuilder() @@ -247,12 +275,19 @@ public ResourceResponse fetchResource(String resourceId){ } } - public ResourceResponse insertResource(ResourceUpdateInsertTask task, BodyPublisher body) { + public ResourceResponse insertResource(ResourceUpdateInsertTask task, ResourceRequest resourceRequest) { logger.info("Inserting {} resources into FDP", task.resource); try { + isAuthenticated(); + URI uri = new URI(this.hostname + "/resource-definitions"); + HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(resourceRequest) + ); + + // Creates request HttpRequest request = HttpRequest.newBuilder() .POST(body) @@ -275,12 +310,18 @@ public ResourceResponse insertResource(ResourceUpdateInsertTask task, BodyPublis } } - public void updateResource(ResourceUpdateInsertTask task, HttpRequest.BodyPublisher body) { + public void updateResource(ResourceUpdateInsertTask task, ResourceResponse resourceResponse) { logger.info("updating resource {} in FDP", task.resource); try { + isAuthenticated(); + URI uri = new URI(this.hostname + "/resource-definitions/" + task.UUID); + HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(resourceResponse) + ); + HttpRequest request = HttpRequest.newBuilder() .PUT(body) .uri(uri) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java index b74a162..1dd0892 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java @@ -5,7 +5,9 @@ import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; import nl.healthri.fdp.uploadschema.dto.request.Schema.ReleaseSchemaRequest; import nl.healthri.fdp.uploadschema.dto.request.Schema.UpdateSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; import nl.healthri.fdp.uploadschema.utils.ResourceMap; @@ -18,24 +20,24 @@ import java.net.http.HttpRequest; import java.util.*; -import java.util.stream.Collectors; -import static nl.healthri.fdp.uploadschema.integration.FdpClient.getAuthorizationToken; @Service public class FdpService { private final IFdpClient fdpClient; - private ObjectMapper objectMapper; + private static final Logger logger = LoggerFactory.getLogger(FdpService.class); @Autowired - public FdpService(IFdpClient fdpClient, ObjectMapper objectMapper) { + public FdpService(IFdpClient fdpClient) { this.fdpClient = fdpClient; - this.objectMapper = objectMapper; } - public static String GetAuthorizationToken(){ + public void authenticate(String username, String password){ + LoginRequest loginRequest = new LoginRequest(username, password); + LoginResponse loginResponse = fdpClient.getAuthToken(loginRequest); + fdpClient.setAuthToken(loginResponse); } public ShapesMap getAllSchemas() { @@ -43,7 +45,7 @@ public ShapesMap getAllSchemas() { return new ShapesMap(schemaDataResponseList); } - public void createSchema(ShapeUpdateInsertTask task) throws JsonProcessingException { + public void createSchema(ShapeUpdateInsertTask task){ ShapesMap shapesMap = getAllSchemas(); UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( @@ -54,16 +56,12 @@ public void createSchema(ShapeUpdateInsertTask task) throws JsonProcessingExcept task.shape, task.url()); - HttpRequest.BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( - this.objectMapper.writeValueAsString(updateSchemaRequest) - ); - - ResourceResponse resourceResponse = fdpClient.insertSchema(task, requestBody); + ResourceResponse resourceResponse = fdpClient.insertSchema(task, updateSchemaRequest); task.uuid = resourceResponse.uuid(); } - public void updateSchema(ShapeUpdateInsertTask task) throws JsonProcessingException { + public void updateSchema(ShapeUpdateInsertTask task){ ShapesMap shapesMap = getAllSchemas(); UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( @@ -74,20 +72,13 @@ public void updateSchema(ShapeUpdateInsertTask task) throws JsonProcessingExcept task.shape, task.url()); - HttpRequest.BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( - this.objectMapper.writeValueAsString(updateSchemaRequest) - ); - - fdpClient.updateSchema(task, requestBody); + fdpClient.updateSchema(task, updateSchemaRequest); } - public void releaseSchema(ShapeUpdateInsertTask task) throws JsonProcessingException { + public void releaseSchema(ShapeUpdateInsertTask task){ ReleaseSchemaRequest releaseSchemaRequest = ReleaseSchemaRequest.of(task.shape, false, task.version); - HttpRequest.BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( - this.objectMapper.writeValueAsString(releaseSchemaRequest) - ); - fdpClient.releaseSchema(task, requestBody); + fdpClient.releaseSchema(task, releaseSchemaRequest); } public ResourceMap getAllResources() { @@ -99,7 +90,7 @@ public ResourceResponse getResourceById(String resourceId) { return fdpClient.fetchResource(resourceId); } - public void createResource(ResourceUpdateInsertTask task) throws JsonProcessingException { + public void createResource(ResourceUpdateInsertTask task){ ResourceRequest resourceRequest = new ResourceRequest( task.resource, task.url(), @@ -108,17 +99,11 @@ public void createResource(ResourceUpdateInsertTask task) throws JsonProcessingE new ArrayList<>(), new ArrayList<>()); - - // Creates payload from DTO - HttpRequest.BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( - this.objectMapper.writeValueAsString(resourceRequest) - ); - - ResourceResponse resourceResponse = fdpClient.insertResource(task, requestBody); + ResourceResponse resourceResponse = fdpClient.insertResource(task, resourceRequest); task.UUID = resourceResponse.uuid(); } - public void updateResource(ResourceUpdateInsertTask task) throws JsonProcessingException { + public void updateResource(ResourceUpdateInsertTask task){ ResourceResponse resourceResponse = fdpClient.fetchResource(task.UUID); if (resourceResponse.children().stream().anyMatch(c -> c.resourceDefinitionUuid().equals(task.childUUuid))) { @@ -130,10 +115,6 @@ public void updateResource(ResourceUpdateInsertTask task) throws JsonProcessingE resourceResponse.children().add(child); } - HttpRequest.BodyPublisher requestBody = HttpRequest.BodyPublishers.ofString( - this.objectMapper.writeValueAsString(resourceResponse) - ); - - fdpClient.updateResource(task, requestBody); + fdpClient.updateResource(task, resourceResponse); } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java index ece835a..33420b5 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java @@ -1,7 +1,11 @@ package nl.healthri.fdp.uploadschema.integration; -import jakarta.annotation.Resource; +import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; +import nl.healthri.fdp.uploadschema.dto.request.Schema.ReleaseSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.request.Schema.UpdateSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; @@ -9,13 +13,16 @@ import java.net.http.HttpRequest; public interface IFdpClient { + void setAuthToken(LoginResponse loginResponse); + LoginResponse getAuthToken(LoginRequest loginRequest); + SchemaDataResponse[] fetchSchemas(); - ResourceResponse insertSchema(ShapeUpdateInsertTask task, HttpRequest.BodyPublisher body); - void updateSchema(ShapeUpdateInsertTask task, HttpRequest.BodyPublisher body); - void releaseSchema(ShapeUpdateInsertTask task, HttpRequest.BodyPublisher body); + ResourceResponse insertSchema(ShapeUpdateInsertTask task, UpdateSchemaRequest updateSchemaRequest); + void updateSchema(ShapeUpdateInsertTask task, UpdateSchemaRequest updateSchemaRequest); + void releaseSchema(ShapeUpdateInsertTask task, ReleaseSchemaRequest releaseSchemaRequest); ResourceResponse[] fetchResources(); ResourceResponse fetchResource(String resourceId); - ResourceResponse insertResource(ResourceUpdateInsertTask task, HttpRequest.BodyPublisher body ); - void updateResource(ResourceUpdateInsertTask task, HttpRequest.BodyPublisher body); + ResourceResponse insertResource(ResourceUpdateInsertTask task, ResourceRequest resourceRequest ); + void updateResource(ResourceUpdateInsertTask task, ResourceResponse resourceResponse); } From f58846f0e1c051c13c0865841e6ae028c4d77ea8 Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Thu, 30 Oct 2025 10:00:30 +0100 Subject: [PATCH 13/51] fix: replaced client dependencies with service and added ignore unused DTO fields when mapping to prevent exceptions. --- .../fdp/uploadschema/SchemaTools.java | 48 ++++++++----------- .../response/Resource/ResourceResponse.java | 3 ++ .../tasks/ResourceUpdateInsertTask.java | 12 +++-- .../tasks/ShapeUpdateInsertTask.java | 7 +-- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index a88b3dd..c3e4b39 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; import nl.healthri.fdp.uploadschema.integration.FdpClient; +import nl.healthri.fdp.uploadschema.integration.FdpService; import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; import nl.healthri.fdp.uploadschema.utils.FileHandler; @@ -25,7 +26,6 @@ import java.util.ArrayList; import static java.util.function.Predicate.not; -import static nl.healthri.fdp.uploadschema.integration.FdpClient.getAuthorizationToken; @CommandLine.Command(name = "SchemaTools utility that create FDP ready Shacls and upload them the the FDP.", mixinStandardHelpOptions = true, version = "SchemaTool v1.0") @@ -60,26 +60,20 @@ public static void main(String... args) { @Override public void run() { try { - final Properties properties = Properties.load(propertyFile); - - - // Create FDP client HttpClient client = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(10)) .build(); ObjectMapper objectMapper = new ObjectMapper(); - LoginRequest loginRequest = new LoginRequest(this.username, this.password); FdpClient fdpClient = new FdpClient(client, this.hostname, objectMapper); - fdpClient.authenticate(loginRequest); - String authToken = FdpClient.getAuthToken(httpClient, this.hostname, this.username, this.password, objectMapper); - - final FdpClient fdpClient = new FdpClient(httpClient, hostname, authToken, objectMapper); + final FdpService fdpService = new FdpService(fdpClient); + final Properties properties = Properties.load(propertyFile); final FileHandler fileHandler = new FileHandler(); + fdpService.authenticate(this.username, this.password); switch (command) { case TEMPLATE -> { convertTemplatesToShaclShapes(properties); @@ -87,11 +81,11 @@ public void run() { mergeShapesForValidation(properties, fileHandler); } case BOTH -> { - createOrUpdateSchemas(fdpClient, properties, force, fileHandler); - addResourceDescriptions(fdpClient, properties); + createOrUpdateSchemas(fdpService, properties, force, fileHandler); + addResourceDescriptions(fdpService, properties); } - case SCHEMA -> createOrUpdateSchemas(fdpClient, properties, force, fileHandler); - case RESOURCE -> addResourceDescriptions(fdpClient, properties); + case SCHEMA -> createOrUpdateSchemas(fdpService, properties, force, fileHandler); + case RESOURCE -> addResourceDescriptions(fdpService, properties); } } catch (IOException io) { throw new RuntimeException(io); @@ -128,46 +122,46 @@ public void mergeShapesForValidation(Properties properties, FileHandler rdfUtils rdfUtils.safeModel(path, m); } - public void createOrUpdateSchemas(FdpClient fdpClient, Properties properties, boolean force, FileHandler fileHandler) throws IOException { + public void createOrUpdateSchemas(FdpService fdpService, Properties properties, boolean force, FileHandler fileHandler) throws IOException { logger.info("Creating/updating schemas from tasks to FDP"); - var shapeTasks = ShapeUpdateInsertTask.createTasks(properties, fdpClient, fileHandler); + var shapeTasks = ShapeUpdateInsertTask.createTasks(fdpService, properties, fileHandler); shapeTasks.forEach(task -> { switch (task.status()) { case INSERT -> { - fdpClient.insertSchema(task); - fdpClient.releaseSchema(task); + fdpService.createSchema(task); + fdpService.releaseSchema(task); } case SAME -> { if (force) { - fdpClient.updateSchema(task); - fdpClient.releaseSchema(task); + fdpService.updateSchema(task); + fdpService.releaseSchema(task); logger.info("Schema {} is updated, it was the same but force was set", task.shape); } else { logger.warn("Schema {} is not updated because it's still the same", task.shape); } } case UPDATE -> { - fdpClient.updateSchema(task); - fdpClient.releaseSchema(task); + fdpService.updateSchema(task); + fdpService.releaseSchema(task); } } }); } - public void addResourceDescriptions(FdpClient fdpClient, Properties properties) { + public void addResourceDescriptions(FdpService fdpService, Properties properties) { logger.info("Adding resource descriptions from resource tasks to FDP"); - var resourceTasks = ResourceUpdateInsertTask.createTask(properties, fdpClient); - resourceTasks.stream().filter(ResourceUpdateInsertTask::isInsert).forEach(fdpClient::insertResource); + var resourceTasks = ResourceUpdateInsertTask.createTask(properties, fdpService); + resourceTasks.stream().filter(ResourceUpdateInsertTask::isInsert).forEach(fdpService::createResource); if (resourceTasks.stream().noneMatch(not(ResourceUpdateInsertTask::isInsert))) { logger.warn("Updating resources is not supported yet, but will try to add children if needed)"); } //add the previous resources as child to parent. - var resourceTasksParents = ResourceUpdateInsertTask.createParentTask(properties, fdpClient); - resourceTasksParents.stream().filter(ResourceUpdateInsertTask::hasChild).forEach(fdpClient::updateResource); + var resourceTasksParents = ResourceUpdateInsertTask.createParentTask(properties, fdpService); + resourceTasksParents.stream().filter(ResourceUpdateInsertTask::hasChild).forEach(fdpService::updateResource); } public enum CommandEnum { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/ResourceResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/ResourceResponse.java index 1a389b7..4c5ed7c 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/ResourceResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/ResourceResponse.java @@ -1,7 +1,10 @@ package nl.healthri.fdp.uploadschema.dto.response.Resource; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + import java.util.ArrayList; +@JsonIgnoreProperties(ignoreUnknown = true) // Description, abstractschema, definition are ignored. public record ResourceResponse( String uuid, String name, diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java index c77a827..f485eec 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java @@ -1,6 +1,7 @@ package nl.healthri.fdp.uploadschema.tasks; import nl.healthri.fdp.uploadschema.integration.FdpClient; +import nl.healthri.fdp.uploadschema.integration.FdpService; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.ResourceMap; import nl.healthri.fdp.uploadschema.utils.ShapesMap; @@ -26,8 +27,8 @@ public ResourceUpdateInsertTask(String resource) { this.resource = resource; } - public static List createParentTask(Properties p, FdpClient fdpClient) { - var resourcesOnFdp = fdpClient.fetchResources(); + public static List createParentTask(Properties p, FdpService fdpService) { + var resourcesOnFdp = fdpService.getAllResources(); return p.resources.entrySet().stream().map(r -> { //now we to update the parent not the resource itself! @@ -40,9 +41,10 @@ public static List createParentTask(Properties p, FdpC }).toList(); } - public static List createTask(Properties p, FdpClient fdpClient) { - var resourcesOnFdp = fdpClient.fetchResources(); - var shapesOnFdp = fdpClient.fetchSchemas(); + public static List createTask(Properties p, FdpService fdpService) { + var resourcesOnFdp = fdpService.getAllResources(); + var shapesOnFdp = fdpService.getAllSchemas(); + return p.resources.entrySet().stream().map(r -> new ResourceUpdateInsertTask(r.getKey()) .addExistingInfo(resourcesOnFdp) .addShapeUUID(shapesOnFdp, r.getValue().schema())).toList(); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java index 36539b8..4c43b70 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java @@ -3,6 +3,7 @@ import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.integration.FdpClient; import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.integration.FdpService; import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.RdfUtils; @@ -35,10 +36,11 @@ public ShapeUpdateInsertTask(String shape) { this.shape = shape; } - public static List createTasks(Properties p, FdpClient fdpClient, FileHandler fileHandler){ + public static List createTasks(FdpService fdpService, Properties p, FileHandler fileHandler){ final List Shapes = p.schemasToPublish; final var files = p.getFiles(); - var shapesOnFdp = fdpClient.fetchSchemas(); + var shapesOnFdp = fdpService.getAllSchemas(); + logger.info("found following shapes on fdp: {}", shapesOnFdp.keySet()); //list of the task we have to do for insert/updating shacls @@ -52,7 +54,6 @@ public static List createTasks(Properties p, FdpClient fd Model newModel = fileHandler.readFiles(ttlFiles); ShapeUpdateInsertTask.model = RdfUtils.modelAsTurtleString(newModel); if (shapesOnFdp.isPresent(r)) { - // todo: add current compare ttl schemas here Model onFdp = shapesOnFdp.getDefinition(r).map(RdfUtils::fromTurtleString).orElse(new LinkedHashModel()); ShapeUpdateInsertTask.version = shapesOnFdp.getVersion(r).map(v -> v.next(requestedVersion)).orElseThrow(); //next patch version ShapeUpdateInsertTask.uuid = shapesOnFdp.getUUID(r).orElseThrow(); From 0aabf532d3fb72c27926dc5eb58703fba4d31b1f Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Thu, 30 Oct 2025 12:58:56 +0100 Subject: [PATCH 14/51] refactor: Removed ResourceMap, ShapeMap and ObjectMap because of unnecessary complexity --- .../uploadschema/integration/FdpClient.java | 10 ++-- .../uploadschema/integration/FdpService.java | 26 ++++---- .../uploadschema/integration/IFdpClient.java | 5 +- .../tasks/ResourceUpdateInsertTask.java | 21 +++++-- .../tasks/ShapeUpdateInsertTask.java | 59 +++++++++++-------- .../fdp/uploadschema/utils/ObjectMap.java | 21 ------- .../fdp/uploadschema/utils/RdfUtils.java | 9 +-- .../fdp/uploadschema/utils/ResourceInfo.java | 3 + .../fdp/uploadschema/utils/ResourceMap.java | 21 ------- .../fdp/uploadschema/utils/SchemaInfo.java | 11 ++++ .../fdp/uploadschema/utils/ShapesMap.java | 32 ---------- .../tasks/ShapeUpdateInsertTaskTest.java | 12 ++-- 12 files changed, 90 insertions(+), 140 deletions(-) delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/utils/ObjectMap.java create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceMap.java create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java index 4dd3f3d..6e44995 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java @@ -27,8 +27,6 @@ // TODO: Throw client exception instead of Runtimeexception (otherwise you hide the error encountered) -// TODO: Split Fdp Client and Service into FdpSchemaClient, FdpResourceClient, etc. -// TODO: @Component public class FdpClient implements IFdpClient { @@ -87,7 +85,7 @@ public LoginResponse getAuthToken(LoginRequest loginRequest) { } } - public SchemaDataResponse[] fetchSchemas() { + public List fetchSchemas() { logger.info("Fetching metadata schemas from FDP"); try { @@ -110,7 +108,7 @@ public SchemaDataResponse[] fetchSchemas() { HttpRequestUtils.handleResponseStatus(response); // Maps response body to object - return objectMapper.readValue(response.body(), SchemaDataResponse[].class); + return List.of(objectMapper.readValue(response.body(), SchemaDataResponse[].class)); } catch (Exception e) { throw new RuntimeException(e); } @@ -217,7 +215,7 @@ public void releaseSchema(ShapeUpdateInsertTask task, ReleaseSchemaRequest relea } } - public ResourceResponse[] fetchResources() { + public List fetchResources() { logger.info("Fetching resources from fdp"); try { @@ -240,7 +238,7 @@ public ResourceResponse[] fetchResources() { HttpRequestUtils.handleResponseStatus(response); // Map response to body - return objectMapper.readValue(response.body(), ResourceResponse[].class); + return List.of(objectMapper.readValue(response.body(), ResourceResponse.class)); } catch (Exception e) { throw new RuntimeException(e); } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java index 1dd0892..16b0d25 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java @@ -1,7 +1,6 @@ package nl.healthri.fdp.uploadschema.integration; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; +import nl.healthri.fdp.uploadschema.Version; import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; import nl.healthri.fdp.uploadschema.dto.request.Schema.ReleaseSchemaRequest; import nl.healthri.fdp.uploadschema.dto.request.Schema.UpdateSchemaRequest; @@ -10,15 +9,16 @@ import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; +import nl.healthri.fdp.uploadschema.utils.ResourceInfo; import nl.healthri.fdp.uploadschema.utils.ResourceMap; -import nl.healthri.fdp.uploadschema.utils.ShapesMap; +import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.net.http.HttpRequest; +import javax.xml.validation.Schema; import java.util.*; @@ -40,13 +40,12 @@ public void authenticate(String username, String password){ fdpClient.setAuthToken(loginResponse); } - public ShapesMap getAllSchemas() { - SchemaDataResponse[] schemaDataResponseList = fdpClient.fetchSchemas(); - return new ShapesMap(schemaDataResponseList); + public List getAllSchemas() { + return fdpClient.fetchSchemas(); } public void createSchema(ShapeUpdateInsertTask task){ - ShapesMap shapesMap = getAllSchemas(); + SchemaInfo shapesMap = getAllSchemas(); UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( task.shape, @@ -62,7 +61,7 @@ public void createSchema(ShapeUpdateInsertTask task){ public void updateSchema(ShapeUpdateInsertTask task){ - ShapesMap shapesMap = getAllSchemas(); + SchemaInfo shapesMap = getAllSchemas(); UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( task.shape, @@ -81,13 +80,8 @@ public void releaseSchema(ShapeUpdateInsertTask task){ fdpClient.releaseSchema(task, releaseSchemaRequest); } - public ResourceMap getAllResources() { - ResourceResponse[] resourceResponseList = fdpClient.fetchResources(); - return new ResourceMap(resourceResponseList); - } - - public ResourceResponse getResourceById(String resourceId) { - return fdpClient.fetchResource(resourceId); + public List getAllResources() { + return fdpClient.fetchResources(); } public void createResource(ResourceUpdateInsertTask task){ diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java index 33420b5..9628aba 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java @@ -11,17 +11,18 @@ import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import java.net.http.HttpRequest; +import java.util.List; public interface IFdpClient { void setAuthToken(LoginResponse loginResponse); LoginResponse getAuthToken(LoginRequest loginRequest); - SchemaDataResponse[] fetchSchemas(); + List fetchSchemas(); ResourceResponse insertSchema(ShapeUpdateInsertTask task, UpdateSchemaRequest updateSchemaRequest); void updateSchema(ShapeUpdateInsertTask task, UpdateSchemaRequest updateSchemaRequest); void releaseSchema(ShapeUpdateInsertTask task, ReleaseSchemaRequest releaseSchemaRequest); - ResourceResponse[] fetchResources(); + List fetchResources(); ResourceResponse fetchResource(String resourceId); ResourceResponse insertResource(ResourceUpdateInsertTask task, ResourceRequest resourceRequest ); void updateResource(ResourceUpdateInsertTask task, ResourceResponse resourceResponse); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java index f485eec..2c83e8a 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java @@ -1,14 +1,17 @@ package nl.healthri.fdp.uploadschema.tasks; -import nl.healthri.fdp.uploadschema.integration.FdpClient; +import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.integration.FdpService; import nl.healthri.fdp.uploadschema.utils.Properties; +import nl.healthri.fdp.uploadschema.utils.ResourceInfo; import nl.healthri.fdp.uploadschema.utils.ResourceMap; -import nl.healthri.fdp.uploadschema.utils.ShapesMap; +import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.regex.Pattern; public class ResourceUpdateInsertTask { @@ -27,8 +30,18 @@ public ResourceUpdateInsertTask(String resource) { this.resource = resource; } + // todo: Map + // todo: Map public static List createParentTask(Properties p, FdpService fdpService) { - var resourcesOnFdp = fdpService.getAllResources(); + + List resourceResponseList = fdpService.getAllResources(); + + Map resourceMap = new HashMap<>(); + for(ResourceResponse resourceResponse : resourceResponseList) { + ResourceInfo resourceInfo = new ResourceInfo(resourceResponse.name(), resourceResponse.uuid()); + resourceMap.put(resourceResponse.name(), resourceInfo); + } + return p.resources.entrySet().stream().map(r -> { //now we to update the parent not the resource itself! @@ -68,7 +81,7 @@ else if (Pattern.matches(".*(s|x|z|ch|sh)$", childName)) { } } - public ResourceUpdateInsertTask addShapeUUID(ShapesMap shapes, String schema) { + public ResourceUpdateInsertTask addShapeUUID(SchemaInfo shapes, String schema) { String name = schema.isBlank() ? resource : schema; var shape = shapes.getUUID(name); shape.ifPresentOrElse(s -> shapeUUUID = s, diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java index 4c43b70..f4acb14 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java @@ -1,13 +1,11 @@ package nl.healthri.fdp.uploadschema.tasks; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.integration.FdpClient; import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.integration.FdpService; -import nl.healthri.fdp.uploadschema.utils.FileHandler; +import nl.healthri.fdp.uploadschema.utils.*; import nl.healthri.fdp.uploadschema.utils.Properties; -import nl.healthri.fdp.uploadschema.utils.RdfUtils; -import nl.healthri.fdp.uploadschema.utils.ShapesMap; import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.model.impl.LinkedHashModel; import org.eclipse.rdf4j.model.util.Models; @@ -15,6 +13,7 @@ import org.slf4j.LoggerFactory; import java.net.URI; +import java.net.URL; import java.util.*; import java.util.stream.Collectors; @@ -37,38 +36,48 @@ public ShapeUpdateInsertTask(String shape) { } public static List createTasks(FdpService fdpService, Properties p, FileHandler fileHandler){ - final List Shapes = p.schemasToPublish; - final var files = p.getFiles(); - var shapesOnFdp = fdpService.getAllSchemas(); + final List schemaList = p.schemasToPublish; + final Map> files = p.getFiles(); + final List schemaDataResponseList = fdpService.getAllSchemas(); + + Map schemaMap = new HashMap<>(); + for(SchemaDataResponse schemaDataResponse : schemaDataResponseList) { + Version version = new Version(schemaDataResponse.latest().version()); + SchemaInfo schemaInfo = new SchemaInfo(version, schemaDataResponse.uuid()); + schemaMap.put(schemaDataResponse.name(), schemaInfo); + } - logger.info("found following shapes on fdp: {}", shapesOnFdp.keySet()); + + + logger.info("found following shapes on fdp: {}", fdpSchemaMap.keySet()); //list of the task we have to do for insert/updating shacls - return Shapes.stream().map(r -> { - var ShapeUpdateInsertTask = new ShapeUpdateInsertTask(r); - var requestedVersion = p.getVersion(); - var ttlFiles = Optional.ofNullable(files.get(r)).orElseThrow(() -> new NoSuchElementException(r + " not present in schema section of yaml-file")); + return schemaList.stream().map(schema -> { + ShapeUpdateInsertTask shapeUpdateInsertTask = new ShapeUpdateInsertTask(schema); + + Version requestedVersion = p.getVersion(); + var ttlFiles = Optional.ofNullable(files.get(schema)).orElseThrow(() -> new NoSuchElementException(r + " not present in schema section of yaml-file")); logger.debug("loading model {} using turtle files: {} ", r, ttlFiles.stream().map(URI::toString).collect(Collectors.joining(", "))); Model newModel = fileHandler.readFiles(ttlFiles); - ShapeUpdateInsertTask.model = RdfUtils.modelAsTurtleString(newModel); - if (shapesOnFdp.isPresent(r)) { - Model onFdp = shapesOnFdp.getDefinition(r).map(RdfUtils::fromTurtleString).orElse(new LinkedHashModel()); - ShapeUpdateInsertTask.version = shapesOnFdp.getVersion(r).map(v -> v.next(requestedVersion)).orElseThrow(); //next patch version - ShapeUpdateInsertTask.uuid = shapesOnFdp.getUUID(r).orElseThrow(); - ShapeUpdateInsertTask.status = Models.isomorphic(onFdp, newModel) ? ShapeStatus.SAME : ShapeStatus.UPDATE; + shapeUpdateInsertTask.model = RdfUtils.modelAsTurtleString(newModel); + if (fdpSchemaMap.containsKey(r)) { + Model onFdp = shapesMapFdp.getDefinition(r).map(RdfUtils::fromTurtleString).orElse(new LinkedHashModel()); + shapeUpdateInsertTask.version = shapesMapFdp.getVersion(r).map(v -> v.next(requestedVersion)).orElseThrow(); //next patch version + shapeUpdateInsertTask.uuid = shapesMapFdp.getUUID(r).orElseThrow(); + shapeUpdateInsertTask.status = Models.isomorphic(onFdp, newModel) ? ShapeStatus.SAME : ShapeStatus.UPDATE; } else { - ShapeUpdateInsertTask.version = requestedVersion; - ShapeUpdateInsertTask.uuid = ""; - ShapeUpdateInsertTask.status = ShapeStatus.INSERT; + shapeUpdateInsertTask.version = requestedVersion; + shapeUpdateInsertTask.uuid = ""; + shapeUpdateInsertTask.status = ShapeStatus.INSERT; } - ShapeUpdateInsertTask.parents = p.getParents(r); - return ShapeUpdateInsertTask; + shapeUpdateInsertTask.parents = p.getParents(r); + return shapeUpdateInsertTask; }).toList(); } - public Set getParentUID(ShapesMap shapesMap) { + public Set getParentUID(SchemaInfo shapesMap) { if (this.parents.isEmpty()) { return Collections.emptySet(); } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/ObjectMap.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/ObjectMap.java deleted file mode 100644 index 9c409bc..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/ObjectMap.java +++ /dev/null @@ -1,21 +0,0 @@ -package nl.healthri.fdp.uploadschema.utils; - -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -public abstract class ObjectMap { - protected Map map; - - public boolean isPresent(String name) { - return map.containsKey(name); - } - - public Set keySet() { - return map.keySet(); - } - - public Optional getValue(String name) { - return Optional.ofNullable(map.get(name)); - } -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java index bdc6576..5c89517 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java @@ -10,22 +10,17 @@ public class RdfUtils { - private RdfUtils() { - //prevent instantiation. - } - public static Model fromTurtleString(String s) { try { return Rio.parse(new StringReader(s), RDFFormat.TURTLE); } catch (IOException ioe) { - //will not happen because we are reading from string. throw new RuntimeException(ioe); } } - public static String modelAsTurtleString(Model m) { + public static String modelAsTurtleString(Model model) { StringWriter sw = new StringWriter(); - Rio.write(m, sw, RDFFormat.TURTLE); + Rio.write(model, sw, RDFFormat.TURTLE); return sw.toString(); } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java new file mode 100644 index 0000000..5e8c990 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java @@ -0,0 +1,3 @@ +package nl.healthri.fdp.uploadschema.utils; + +public record ResourceInfo(String name, String uuid) {} \ No newline at end of file diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceMap.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceMap.java deleted file mode 100644 index 8fd4509..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceMap.java +++ /dev/null @@ -1,21 +0,0 @@ -package nl.healthri.fdp.uploadschema.utils; - -import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; - -import java.util.Arrays; -import java.util.Optional; -import java.util.stream.Collectors; - -public class ResourceMap extends ObjectMap { - - public ResourceMap(ResourceResponse[] resourceResponses) { - map = Arrays.stream(resourceResponses).collect(Collectors.toMap(ResourceResponse::name, rr -> new ResourceInfo(rr.name(), rr.uuid()))); - } - - public Optional getUUID(String name) { - return getValue(name).map(ResourceInfo::uuid); - } - - public record ResourceInfo(String name, String uuid) { - } -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java new file mode 100644 index 0000000..b9d5b2f --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java @@ -0,0 +1,11 @@ +package nl.healthri.fdp.uploadschema.utils; + +import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; + +import java.util.Arrays; +import java.util.Optional; +import java.util.stream.Collectors; + +public record SchemaInfo(Version version, String uuid) { +} \ No newline at end of file diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java deleted file mode 100644 index f9c8568..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/ShapesMap.java +++ /dev/null @@ -1,32 +0,0 @@ -package nl.healthri.fdp.uploadschema.utils; - -import nl.healthri.fdp.uploadschema.Version; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; - -import java.util.Arrays; -import java.util.Optional; -import java.util.stream.Collectors; - -public class ShapesMap extends ObjectMap { - - public ShapesMap(SchemaDataResponse[] repsonses) { - this.map = Arrays - .stream(repsonses) - .collect(Collectors.toMap(SchemaDataResponse::name, sr -> new SchemaInfo(new Version(sr.latest().version()), sr.uuid(), sr.latest().definition()))); - } - - public Optional getDefinition(String name) { - return getValue(name).map(SchemaInfo::definition); - } - - public Optional getVersion(String name) { - return getValue(name).map(SchemaInfo::version); - } - - public Optional getUUID(String name) { - return getValue(name).map(SchemaInfo::uuid); - } - - public record SchemaInfo(Version version, String uuid, String definition) { - } -} diff --git a/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java b/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java index fd23ab1..eaa2197 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java @@ -6,7 +6,7 @@ import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.RdfUtils; -import nl.healthri.fdp.uploadschema.utils.ShapesMap; +import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -39,7 +39,7 @@ void testCreateTasks_updated_shape() { Mockito.when(props.getParents("TestShape")).thenReturn(Set.of("ParentShape")); // Mock FDP and its fetchSchemaFromFDP result - ShapesMap shapesOnFdp = createFdpShapeMap( + SchemaInfo shapesOnFdp = createFdpShapeMap( createFdpResponse("TestShape", "", "1.0.0", "uuid")); FdpClient fdpClient = Mockito.mock(FdpClient.class); @@ -80,7 +80,7 @@ void testCreateTasks_identical_shape() { Mockito.when(props.getParents("TestShape")).thenReturn(Set.of("ParentShape")); // Mock FDP and its fetchSchemaFromFDP result - ShapesMap shapesOnFdp = createFdpShapeMap( + SchemaInfo shapesOnFdp = createFdpShapeMap( createFdpResponse("TestShape", getShapeModel1(), "1.0.0", "uuid")); FdpClient fdpClient = Mockito.mock(FdpClient.class); @@ -121,7 +121,7 @@ void testCreateTasks_new() { Mockito.when(props.getParents("TestShape")).thenReturn(Set.of("ParentShape")); // Mock FDP and its fetchSchemaFromFDP result - ShapesMap shapesOnFdp = createFdpShapeMap( + SchemaInfo shapesOnFdp = createFdpShapeMap( createFdpResponse("JustAnotherShape", "", "1.0.0", "uuid")); FdpClient fdpClient = Mockito.mock(FdpClient.class); @@ -143,8 +143,8 @@ void testCreateTasks_new() { assertEquals(ShapeUpdateInsertTask.ShapeStatus.INSERT, task.status); } - private ShapesMap createFdpShapeMap(SchemaDataResponse... responses) { - return new ShapesMap(responses); + private SchemaInfo createFdpShapeMap(SchemaDataResponse... responses) { + return new SchemaInfo(responses); } private SchemaDataResponse createFdpResponse(String name, String definition, String version, String uuid) { From a53c102c3b04f60071bea0981a751df4ff951bff Mon Sep 17 00:00:00 2001 From: Sean Berrie Date: Mon, 3 Nov 2025 10:24:51 +0100 Subject: [PATCH 15/51] refactor: added Resource and Shape Task domain and service --- .../fdp/uploadschema/SchemaTools.java | 3 +- .../fdp/uploadschema/domain/ResourceTask.java | 24 ++++++ .../fdp/uploadschema/domain/ShapeTask.java | 4 + .../uploadschema/integration/FdpService.java | 25 ++++-- .../tasks/ResourceTaskService.java | 17 ++++ .../tasks/ResourceUpdateInsertTask.java | 86 +++++++++++++------ .../uploadschema/tasks/ShapeTaskService.java | 4 + .../tasks/ShapeUpdateInsertTask.java | 50 +++++++---- .../fdp/uploadschema/utils/SchemaInfo.java | 2 +- 9 files changed, 160 insertions(+), 55 deletions(-) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index c3e4b39..43f56ca 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -65,15 +65,14 @@ public void run() { .build(); ObjectMapper objectMapper = new ObjectMapper(); - FdpClient fdpClient = new FdpClient(client, this.hostname, objectMapper); final FdpService fdpService = new FdpService(fdpClient); final Properties properties = Properties.load(propertyFile); final FileHandler fileHandler = new FileHandler(); - fdpService.authenticate(this.username, this.password); + switch (command) { case TEMPLATE -> { convertTemplatesToShaclShapes(properties); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java b/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java new file mode 100644 index 0000000..b39bd58 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java @@ -0,0 +1,24 @@ +package nl.healthri.fdp.uploadschema.domain; + +public class ResourceTask { + public final String resource; + public String UUID; + public String shapeUUUID; + public String childUUuid; + public String childRelationIri; + public String childName; + + public ResourceTask(String resource, String uuid, String shapeUUUID, String childUUuid, String childRelationIri, String childName){ + this.resource = resource; + this.UUID = uuid; + this.shapeUUUID = shapeUUUID; + this.childUUuid = childUUuid; + this.childRelationIri = childRelationIri; + this.childName = childName; + + } + + public Validate(){ + + } +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java b/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java new file mode 100644 index 0000000..b0e2a4f --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java @@ -0,0 +1,4 @@ +package nl.healthri.fdp.uploadschema.domain; + +public class ShapeTask { +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java index 16b0d25..b34e432 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java @@ -9,8 +9,6 @@ import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; -import nl.healthri.fdp.uploadschema.utils.ResourceInfo; -import nl.healthri.fdp.uploadschema.utils.ResourceMap; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import org.slf4j.Logger; @@ -45,13 +43,21 @@ public List getAllSchemas() { } public void createSchema(ShapeUpdateInsertTask task){ - SchemaInfo shapesMap = getAllSchemas(); + List schemaDataResponseList = getAllSchemas(); + + Map schemaInfoMap = new HashMap<>(); + for(SchemaDataResponse schemaDataResponse : schemaDataResponseList) { + Version version = new Version(schemaDataResponse.latest().version()); + SchemaInfo schemaInfo = new SchemaInfo(version, schemaDataResponse.uuid(), schemaDataResponse.latest().definition()); + schemaInfoMap.put(schemaDataResponse.name(), schemaInfo); + } + UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( task.shape, task.description(), false, task.model, - task.getParentUID(shapesMap), + task.getParentUID(schemaInfoMap), task.shape, task.url()); @@ -61,13 +67,20 @@ public void createSchema(ShapeUpdateInsertTask task){ public void updateSchema(ShapeUpdateInsertTask task){ - SchemaInfo shapesMap = getAllSchemas(); + List schemaDataResponseList = getAllSchemas(); + + Map schemaInfoMap = new HashMap<>(); + for(SchemaDataResponse schemaDataResponse : schemaDataResponseList) { + Version version = new Version(schemaDataResponse.latest().version()); + SchemaInfo schemaInfo = new SchemaInfo(version, schemaDataResponse.uuid(), schemaDataResponse.latest().definition()); + schemaInfoMap.put(schemaDataResponse.name(), schemaInfo); + } UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( task.shape, task.description(), false, task.model, - task.getParentUID(shapesMap), + task.getParentUID(schemaInfoMap), task.shape, task.url()); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java new file mode 100644 index 0000000..2a61f93 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java @@ -0,0 +1,17 @@ +package nl.healthri.fdp.uploadschema.tasks; + +import nl.healthri.fdp.uploadschema.integration.FdpService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ResourceTaskService { + public FdpService fdpService; + + private static final Logger logger = LoggerFactory.getLogger(nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask.class); + + public ResourceTaskService(FdpService fdpService) { + this.fdpService = fdpService; + } + + +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java index 2c83e8a..34ba75d 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java @@ -1,10 +1,11 @@ package nl.healthri.fdp.uploadschema.tasks; +import nl.healthri.fdp.uploadschema.Version; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.integration.FdpService; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.ResourceInfo; -import nl.healthri.fdp.uploadschema.utils.ResourceMap; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,10 +37,10 @@ public static List createParentTask(Properties p, FdpS List resourceResponseList = fdpService.getAllResources(); - Map resourceMap = new HashMap<>(); + Map fdpResourceMap = new HashMap<>(); for(ResourceResponse resourceResponse : resourceResponseList) { ResourceInfo resourceInfo = new ResourceInfo(resourceResponse.name(), resourceResponse.uuid()); - resourceMap.put(resourceResponse.name(), resourceInfo); + fdpResourceMap.put(resourceResponse.name(), resourceInfo); } @@ -48,19 +49,39 @@ public static List createParentTask(Properties p, FdpS var parentName = r.getValue().parentResource(); var childName = r.getKey(); var childIri = r.getValue().parentRelationIri(); + return new ResourceUpdateInsertTask(parentName) - .addExistingInfo(resourcesOnFdp) //adds uuid - .addChildInfo(childName, childIri, resourcesOnFdp); + .addExistingInfo(fdpResourceMap) //adds uuid + .addChildInfo(childName, childIri, fdpResourceMap); }).toList(); } public static List createTask(Properties p, FdpService fdpService) { - var resourcesOnFdp = fdpService.getAllResources(); - var shapesOnFdp = fdpService.getAllSchemas(); + List resourceResponseList = fdpService.getAllResources(); + List schemaDataResponseList = fdpService.getAllSchemas(); + + Map fdpResourceMap = new HashMap<>(); + for(ResourceResponse resourceResponse : resourceResponseList) { + ResourceInfo resourceInfo = new ResourceInfo(resourceResponse.name(), resourceResponse.uuid()); + fdpResourceMap.put(resourceResponse.name(), resourceInfo); + } + + Map schemaInfoMap = new HashMap<>(); + for(SchemaDataResponse schemaDataResponse : schemaDataResponseList) { + Version version = new Version(schemaDataResponse.latest().version()); + + SchemaInfo schemaInfo = new SchemaInfo( + version, + schemaDataResponse.uuid(), + schemaDataResponse.latest().definition()); + + schemaInfoMap.put(schemaDataResponse.name(), schemaInfo); + } + return p.resources.entrySet().stream().map(r -> new ResourceUpdateInsertTask(r.getKey()) - .addExistingInfo(resourcesOnFdp) - .addShapeUUID(shapesOnFdp, r.getValue().schema())).toList(); + .addExistingInfo(fdpResourceMap) + .addShapeUUID(schemaInfoMap, r.getValue().schema())).toList(); } public String pluralName() { @@ -81,11 +102,16 @@ else if (Pattern.matches(".*(s|x|z|ch|sh)$", childName)) { } } - public ResourceUpdateInsertTask addShapeUUID(SchemaInfo shapes, String schema) { - String name = schema.isBlank() ? resource : schema; - var shape = shapes.getUUID(name); - shape.ifPresentOrElse(s -> shapeUUUID = s, - () -> logger.error("Can't find shape: {} ", resource)); + public ResourceUpdateInsertTask addShapeUUID(Map fdpSchemaInfoMap, String schema) { + String name = schema.isBlank() ? this.resource : schema; + String fdpSchemaUUID = fdpSchemaInfoMap.get(name).uuid(); + + if (fdpSchemaUUID == null || fdpSchemaUUID.isEmpty()) { + logger.error("Can't find shape: {} ", resource); + return this; + } + + this.shapeUUUID = fdpSchemaUUID; return this; } @@ -101,23 +127,29 @@ public boolean hasChild() { return childUUuid != null; } - public ResourceUpdateInsertTask addExistingInfo(ResourceMap resourceOnFdp) { - var uuid = resourceOnFdp.getUUID(resource); - exists = uuid.isPresent(); - uuid.ifPresentOrElse(u -> this.UUID = u, - () -> logger.warn("update of resource is not supported yet")); + public ResourceUpdateInsertTask addExistingInfo(Map fdpResourcesMap) { + String uuid = fdpResourcesMap.get(this.resource).uuid(); + if(uuid == null || uuid.isEmpty()) { + logger.warn("Can't find existing info for resource: {} ", this.resource); + } + + this.exists = true; + this.UUID = uuid; return this; - } +} - public ResourceUpdateInsertTask addChildInfo(String name, String relationIri, ResourceMap resourceOnFdp) { - var uuid = resourceOnFdp.getUUID(name); - if (uuid.isPresent()) { - childName = name; - childRelationIri = relationIri; - childUUuid = uuid.get(); - } else { + public ResourceUpdateInsertTask addChildInfo(String name, String relationIri, Map fdpResourcesMap) { + String uuid = fdpResourcesMap.get(this.resource).uuid(); + if(uuid == null || uuid.isEmpty()) { logger.error("Child resource is not found {} ", name); + return this; } + + this.childUUuid = uuid; + this.childRelationIri = relationIri; + this.childName = name; return this; } + + } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java new file mode 100644 index 0000000..8149805 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java @@ -0,0 +1,4 @@ +package nl.healthri.fdp.uploadschema.tasks; + +public class ShapeTaskService { +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java index f4acb14..90966e8 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java @@ -12,6 +12,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.xml.validation.Schema; import java.net.URI; import java.net.URL; import java.util.*; @@ -38,52 +39,63 @@ public ShapeUpdateInsertTask(String shape) { public static List createTasks(FdpService fdpService, Properties p, FileHandler fileHandler){ final List schemaList = p.schemasToPublish; final Map> files = p.getFiles(); + final List schemaDataResponseList = fdpService.getAllSchemas(); - Map schemaMap = new HashMap<>(); + Map schemaInfoMap = new HashMap<>(); for(SchemaDataResponse schemaDataResponse : schemaDataResponseList) { Version version = new Version(schemaDataResponse.latest().version()); - SchemaInfo schemaInfo = new SchemaInfo(version, schemaDataResponse.uuid()); - schemaMap.put(schemaDataResponse.name(), schemaInfo); + SchemaInfo schemaInfo = new SchemaInfo( + version, + schemaDataResponse.uuid(), + schemaDataResponse.latest().definition()); + schemaInfoMap.put(schemaDataResponse.name(), schemaInfo); } - - - logger.info("found following shapes on fdp: {}", fdpSchemaMap.keySet()); + logger.info("found following shapes on fdp: {}", schemaInfoMap.keySet()); //list of the task we have to do for insert/updating shacls - return schemaList.stream().map(schema -> { - ShapeUpdateInsertTask shapeUpdateInsertTask = new ShapeUpdateInsertTask(schema); - + return schemaList.stream().map(schemaTitle -> { + ShapeUpdateInsertTask shapeUpdateInsertTask = new ShapeUpdateInsertTask(schemaTitle); Version requestedVersion = p.getVersion(); - var ttlFiles = Optional.ofNullable(files.get(schema)).orElseThrow(() -> new NoSuchElementException(r + " not present in schema section of yaml-file")); + var ttlFiles = Optional.ofNullable(files.get(schemaTitle)).orElseThrow(() -> new NoSuchElementException(schemaTitle + " not present in schema section of yaml-file")); - logger.debug("loading model {} using turtle files: {} ", r, ttlFiles.stream().map(URI::toString).collect(Collectors.joining(", "))); + logger.debug("loading model {} using turtle files: {} ", schemaTitle, ttlFiles.stream().map(URI::toString).collect(Collectors.joining(", "))); Model newModel = fileHandler.readFiles(ttlFiles); shapeUpdateInsertTask.model = RdfUtils.modelAsTurtleString(newModel); - if (fdpSchemaMap.containsKey(r)) { - Model onFdp = shapesMapFdp.getDefinition(r).map(RdfUtils::fromTurtleString).orElse(new LinkedHashModel()); - shapeUpdateInsertTask.version = shapesMapFdp.getVersion(r).map(v -> v.next(requestedVersion)).orElseThrow(); //next patch version - shapeUpdateInsertTask.uuid = shapesMapFdp.getUUID(r).orElseThrow(); - shapeUpdateInsertTask.status = Models.isomorphic(onFdp, newModel) ? ShapeStatus.SAME : ShapeStatus.UPDATE; + + if (schemaInfoMap.containsKey(schemaTitle)) { + // Gets matching schema title from map + SchemaInfo matchingFdpSchema = schemaInfoMap.get(schemaTitle); + + // Gets schema model as .ttl format + Model fdpSchemaModel = RdfUtils.fromTurtleString(matchingFdpSchema.definition()); + + // Sets task variables + shapeUpdateInsertTask.version = matchingFdpSchema.version().next(requestedVersion); + shapeUpdateInsertTask.uuid = matchingFdpSchema.uuid(); + shapeUpdateInsertTask.status = Models.isomorphic(fdpSchemaModel, newModel) ? ShapeStatus.SAME : ShapeStatus.UPDATE; } else { + shapeUpdateInsertTask.version = requestedVersion; shapeUpdateInsertTask.uuid = ""; shapeUpdateInsertTask.status = ShapeStatus.INSERT; } - shapeUpdateInsertTask.parents = p.getParents(r); + + shapeUpdateInsertTask.parents = p.getParents(schemaTitle); return shapeUpdateInsertTask; }).toList(); } - public Set getParentUID(SchemaInfo shapesMap) { + public Set getParentUID(Map schemaMap) { if (this.parents.isEmpty()) { return Collections.emptySet(); } return this.parents.stream() - .map(shapesMap::getUUID).flatMap(Optional::stream) + .map(schemaMap::get) // SchemaInfo + .map(SchemaInfo::uuid) // SchemaInfo.UUID .collect(Collectors.toSet()); } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java index b9d5b2f..caf6447 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java @@ -7,5 +7,5 @@ import java.util.Optional; import java.util.stream.Collectors; -public record SchemaInfo(Version version, String uuid) { +public record SchemaInfo(Version version, String uuid, String definition) { } \ No newline at end of file From 8df183261defd8f856a0a74186b5840288445c1c Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Mon, 3 Nov 2025 15:05:26 +0100 Subject: [PATCH 16/51] refactor: Split resourceUpdateInsertTask into service and domain layer --- .../fdp/uploadschema/domain/ResourceTask.java | 100 +++++++++++++++++- .../fdp/uploadschema/domain/ShapeTask.java | 51 +++++++++ .../domain/enums/ShapeStatus.java | 5 + .../tasks/ResourceTaskService.java | 72 ++++++++++++- .../tasks/ResourceUpdateInsertTask.java | 77 ++++---------- .../uploadschema/tasks/SchemaToolService.java | 11 ++ .../uploadschema/tasks/ShapeTaskService.java | 21 ++++ .../tasks/ShapeUpdateInsertTask.java | 11 +- .../fdp/uploadschema/utils/ResourceInfo.java | 19 +++- .../fdp/uploadschema/utils/SchemaInfo.java | 25 ++++- 10 files changed, 316 insertions(+), 76 deletions(-) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/domain/enums/ShapeStatus.java create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java diff --git a/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java b/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java index b39bd58..14cec52 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java @@ -1,5 +1,14 @@ package nl.healthri.fdp.uploadschema.domain; +import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; +import nl.healthri.fdp.uploadschema.utils.ResourceInfo; +import nl.healthri.fdp.uploadschema.utils.SchemaInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; +import java.util.regex.Pattern; + public class ResourceTask { public final String resource; public String UUID; @@ -7,18 +16,105 @@ public class ResourceTask { public String childUUuid; public String childRelationIri; public String childName; + public boolean exists; + + private static final Logger logger = LoggerFactory.getLogger(ResourceTask.class); + - public ResourceTask(String resource, String uuid, String shapeUUUID, String childUUuid, String childRelationIri, String childName){ + public ResourceTask(String resource, String uuid, String shapeUUUID) { this.resource = resource; this.UUID = uuid; this.shapeUUUID = shapeUUUID; + this.exists = false; + } + + public ResourceTask(String resource, String uuid, String shapeUUUID, String childUUUID, String childRelationIri, String childName) { + this.resource = resource; + this.UUID = uuid; + this.shapeUUUID = shapeUUUID; + this.childUUuid = childUUUID; + this.childRelationIri = childRelationIri; + this.childName = childName; + this.exists = false; + } + + public void addChildInfo(String childUUuid, String childRelationIri, String childName) { this.childUUuid = childUUuid; this.childRelationIri = childRelationIri; this.childName = childName; + } + + public void validate() { + if (this.resource == null || this.resource.isEmpty()) { + logger.error("Invalid: resource is required"); + } + if (this.UUID == null || this.UUID.isEmpty()) { + logger.error("Invalid: UUID is required"); + } + if (this.shapeUUUID == null || this.shapeUUUID.isEmpty()) { + logger.error("Invalid: shapeUUUID is required"); + } + if (this.childUUuid != null && (this.childRelationIri == null || this.childRelationIri.isEmpty())) { + logger.error("ÃŒnvalid: childRelationIri should be set if childUUuid is provided"); + } + if (this.childRelationIri != null && (this.childUUuid == null || this.childUUuid.isEmpty())) { + logger.error("ÃŒnvalid: childUUuid should be set if childRelationIri is provided"); + } + if (this.childName != null && this.childName.isEmpty()) { + logger.error("ÃŒnvalid: childName is empty"); + } + } + + public String pluralName() { + //FIXME shape datasetSeries is already plural form. + if (this.childName.toLowerCase().endsWith("ies")) return this.childName; + + // Rule 1: Words ending in consonant + "y" -> replace "y" with "ies" + if (Pattern.matches(".*[^aeiou]y$", this.childName)) { + return this.childName.replaceAll("y$", "ies"); + } + // Rule 2: Words ending in "s", "x", "z", "ch", or "sh" -> add "es" + else if (Pattern.matches(".*(s|x|z|ch|sh)$", this.childName)) { + return this.childName + "es"; + } + // Default rule: Just add "s" + else { + return this.childName + "s"; + } + } + public void addShapeUUID(Map fdpSchemaInfoMap, String schema) { + String name = schema.isBlank() ? this.resource : schema; + String fdpSchemaUUID = fdpSchemaInfoMap.get(name).uuid(); + + if (fdpSchemaUUID == null || fdpSchemaUUID.isEmpty()) { + logger.error("Can't find shape: {} ", this.resource); + } + + this.shapeUUUID = fdpSchemaUUID; } - public Validate(){ + public String url() { + return this.resource.toLowerCase().replaceAll(" ", ""); + } + public boolean isInsert() { + return !this.exists; } + + public boolean hasChild() { + return this.childUUuid != null; + } + + public void addExistingInfo(Map fdpResourcesMap) { + String uuid = fdpResourcesMap.get(this.resource).uuid(); + if(uuid == null || uuid.isEmpty()) { + logger.warn("Can't find existing info for resource: {} ", this.resource); + } + + this.exists = true; + this.UUID = uuid; + } + + } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java b/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java index b0e2a4f..6d46d04 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java @@ -1,4 +1,55 @@ package nl.healthri.fdp.uploadschema.domain; +import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.util.Set; + public class ShapeTask { + public final String shape; + public Version version; + public String uuid; + public Set parents; // Names of parents for this schema + public String model; + public ShapeStatus status; + + private static final Logger logger = LoggerFactory.getLogger(ShapeTask.class); + + public ShapeTask(String shape, Version version, String uuid, Set parents, String model, ShapeStatus status) { + this.shape = shape; + this.version = version; + this.uuid = uuid; + this.parents = parents; + this.model = model; + this.status = status; + + this.validate(); + } + + public void validate() { + if (shape == null || shape.isEmpty()) { + logger.error("Invalid: shape is required"); + return; + } + if (version == null) { + logger.error("Invalid: version is required"); + return; + } + if (uuid == null || uuid.isEmpty()) { + logger.error("Invalid: uuid is required"); + return; + } + if (model == null || model.isEmpty()) { + logger.error("Invalid: model is required"); + return; + } + if (status == null) { + logger.error("Invalid: status is required"); + return; + } + if (parents == null || parents.isEmpty()) { + logger.error("Invalid: no parents defined for shape '{}'", shape); + } + } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/domain/enums/ShapeStatus.java b/src/main/java/nl/healthri/fdp/uploadschema/domain/enums/ShapeStatus.java new file mode 100644 index 0000000..59f1fe1 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/domain/enums/ShapeStatus.java @@ -0,0 +1,5 @@ +package nl.healthri.fdp.uploadschema.domain.enums; + +public enum ShapeStatus { + INSERT, UPDATE, SAME +} \ No newline at end of file diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java index 2a61f93..e2c88f6 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java @@ -1,17 +1,85 @@ package nl.healthri.fdp.uploadschema.tasks; +import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.domain.ResourceTask; +import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.integration.FdpService; +import nl.healthri.fdp.uploadschema.utils.Properties; +import nl.healthri.fdp.uploadschema.utils.ResourceInfo; +import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static java.util.stream.Collectors.toList; +import static nl.healthri.fdp.uploadschema.utils.ResourceInfo.createResourceInfoMap; +import static nl.healthri.fdp.uploadschema.utils.SchemaInfo.createSchemaInfoMap; + public class ResourceTaskService { public FdpService fdpService; + public Properties properties; - private static final Logger logger = LoggerFactory.getLogger(nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask.class); + private static final Logger logger = LoggerFactory.getLogger(ResourceTaskService.class); public ResourceTaskService(FdpService fdpService) { - this.fdpService = fdpService; + this.fdpService = fdpService; + } + + public List createTasks() { + List resourceResponseList = this.fdpService.getAllResources(); + Map resourceInfoMap = createResourceInfoMap(resourceResponseList); + + List schemaDataResponseList = this.fdpService.getAllSchemas(); + Map schemaInfoMap = createSchemaInfoMap(schemaDataResponseList); + + + // Build and validate ResourceTasks + return properties.resources.entrySet().stream().map(entry -> { + String resource = entry.getKey(); + + // Gets resource id + String resourceUuid = resourceInfoMap.get(resource).uuid(); + + // Get schema id + String schema = entry.getValue().schema(); + String name = schema.isBlank() ? resource : schema; + String schemaUUID = schemaInfoMap.get(name).uuid(); + + return new ResourceTask( + resource, + resourceUuid, + schemaUUID + ); + }).toList(); } + public List createParentTasks() { + List resourceResponseList = this.fdpService.getAllResources(); + Map resourceInfoMap = createResourceInfoMap(resourceResponseList); + + return this.properties.resources.entrySet().stream().map(entry -> { + String parentName = entry.getValue().parentResource(); + // Gets resource id + String resourceUuid = resourceInfoMap.get(parentName).uuid(); + + // Get child attributes + String childName = entry.getKey(); + String childIri = entry.getValue().parentRelationIri(); + String childUuid = resourceInfoMap.get(parentName).uuid(); + + return new ResourceTask( + parentName, + resourceUuid, + null, + childUuid, + childIri, + childName + ); + }).toList(); + } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java index 34ba75d..3ec69a2 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java @@ -56,34 +56,33 @@ public static List createParentTask(Properties p, FdpS }).toList(); } - public static List createTask(Properties p, FdpService fdpService) { - List resourceResponseList = fdpService.getAllResources(); - List schemaDataResponseList = fdpService.getAllSchemas(); - - Map fdpResourceMap = new HashMap<>(); - for(ResourceResponse resourceResponse : resourceResponseList) { - ResourceInfo resourceInfo = new ResourceInfo(resourceResponse.name(), resourceResponse.uuid()); - fdpResourceMap.put(resourceResponse.name(), resourceInfo); + public ResourceUpdateInsertTask addExistingInfo(Map fdpResourcesMap) { + String uuid = fdpResourcesMap.get(this.resource).uuid(); + if(uuid == null || uuid.isEmpty()) { + logger.warn("Can't find existing info for resource: {} ", this.resource); } - Map schemaInfoMap = new HashMap<>(); - for(SchemaDataResponse schemaDataResponse : schemaDataResponseList) { - Version version = new Version(schemaDataResponse.latest().version()); - - SchemaInfo schemaInfo = new SchemaInfo( - version, - schemaDataResponse.uuid(), - schemaDataResponse.latest().definition()); + this.exists = true; + this.UUID = uuid; + return this; +} - schemaInfoMap.put(schemaDataResponse.name(), schemaInfo); + public ResourceUpdateInsertTask addChildInfo(String name, String relationIri, Map fdpResourcesMap) { + String uuid = fdpResourcesMap.get(this.resource).uuid(); + if(uuid == null || uuid.isEmpty()) { + logger.error("Child resource is not found {} ", name); + return this; } - - return p.resources.entrySet().stream().map(r -> new ResourceUpdateInsertTask(r.getKey()) - .addExistingInfo(fdpResourceMap) - .addShapeUUID(schemaInfoMap, r.getValue().schema())).toList(); + this.childUUuid = uuid; + this.childRelationIri = relationIri; + this.childName = name; + return this; } + + + public String pluralName() { //FIXME shape datasetSeries is already plural form. if (childName.toLowerCase().endsWith("ies")) return childName; @@ -102,18 +101,7 @@ else if (Pattern.matches(".*(s|x|z|ch|sh)$", childName)) { } } - public ResourceUpdateInsertTask addShapeUUID(Map fdpSchemaInfoMap, String schema) { - String name = schema.isBlank() ? this.resource : schema; - String fdpSchemaUUID = fdpSchemaInfoMap.get(name).uuid(); - - if (fdpSchemaUUID == null || fdpSchemaUUID.isEmpty()) { - logger.error("Can't find shape: {} ", resource); - return this; - } - this.shapeUUUID = fdpSchemaUUID; - return this; - } public String url() { return resource.toLowerCase().replaceAll(" ", ""); @@ -127,29 +115,4 @@ public boolean hasChild() { return childUUuid != null; } - public ResourceUpdateInsertTask addExistingInfo(Map fdpResourcesMap) { - String uuid = fdpResourcesMap.get(this.resource).uuid(); - if(uuid == null || uuid.isEmpty()) { - logger.warn("Can't find existing info for resource: {} ", this.resource); - } - - this.exists = true; - this.UUID = uuid; - return this; -} - - public ResourceUpdateInsertTask addChildInfo(String name, String relationIri, Map fdpResourcesMap) { - String uuid = fdpResourcesMap.get(this.resource).uuid(); - if(uuid == null || uuid.isEmpty()) { - logger.error("Child resource is not found {} ", name); - return this; - } - - this.childUUuid = uuid; - this.childRelationIri = relationIri; - this.childName = name; - return this; - } - - } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java new file mode 100644 index 0000000..45b9187 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java @@ -0,0 +1,11 @@ +package nl.healthri.fdp.uploadschema.tasks; + +import nl.healthri.fdp.uploadschema.integration.FdpService; + +public class SchemaToolService { + public SchemaToolService() { + + } + + +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java index 8149805..fc6799a 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java @@ -1,4 +1,25 @@ package nl.healthri.fdp.uploadschema.tasks; +import nl.healthri.fdp.uploadschema.integration.FdpClient; +import nl.healthri.fdp.uploadschema.integration.FdpService; +import nl.healthri.fdp.uploadschema.utils.FileHandler; +import nl.healthri.fdp.uploadschema.utils.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + public class ShapeTaskService { + public FdpService fdpService; + public FileHandler fileHandler; + public Properties properties; + + private static final Logger logger = LoggerFactory.getLogger(ShapeTaskService.class); + + public ShapeTaskService(FdpService fdpService, FileHandler fileHandler, Properties properties) { + this.fdpService = fdpService; + this.fileHandler = fileHandler; + this.properties = properties; + } + + } + diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java index 90966e8..9bc3a87 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java @@ -21,16 +21,7 @@ public class ShapeUpdateInsertTask { private static final Logger logger = LoggerFactory.getLogger(ShapeUpdateInsertTask.class); - public final String shape; - public Version version; - public String uuid; - public Set parents; //name of parents for this schema. - public String model; - public ShapeStatus status; - - public enum ShapeStatus { - INSERT, UPDATE, SAME - } + public ShapeUpdateInsertTask(String shape) { this.shape = shape; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java index 5e8c990..5d2261a 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java @@ -1,3 +1,20 @@ package nl.healthri.fdp.uploadschema.utils; -public record ResourceInfo(String name, String uuid) {} \ No newline at end of file +import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public record ResourceInfo(String name, String uuid) { + + public static Map createResourceInfoMap(List resourceResponseList){ + Map fdpResourceMap = new HashMap<>(); + for(ResourceResponse resourceResponse : resourceResponseList) { + ResourceInfo resourceInfo = new ResourceInfo(resourceResponse.name(), resourceResponse.uuid()); + fdpResourceMap.put(resourceResponse.name(), resourceInfo); + } + + return fdpResourceMap; + } +} \ No newline at end of file diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java index caf6447..f74c345 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java @@ -3,9 +3,26 @@ import nl.healthri.fdp.uploadschema.Version; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import java.util.Arrays; -import java.util.Optional; -import java.util.stream.Collectors; +import java.util.HashMap; +import java.util.List; +import java.util.Map; public record SchemaInfo(Version version, String uuid, String definition) { -} \ No newline at end of file + + public static Map createSchemaInfoMap(List schemaDataResponseList) { + Map schemaInfoMap = new HashMap<>(); + for (SchemaDataResponse schemaDataResponse : schemaDataResponseList) { + Version version = new Version(schemaDataResponse.latest().version()); + + SchemaInfo schemaInfo = new SchemaInfo( + version, + schemaDataResponse.uuid(), + schemaDataResponse.latest().definition() + ); + + schemaInfoMap.put(schemaDataResponse.name(), schemaInfo); + } + + return schemaInfoMap; + } +} From b6ea53a00c6d0c1054afc7bb1cb286743a416a12 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Mon, 3 Nov 2025 16:23:37 +0100 Subject: [PATCH 17/51] refactor: refactored SchemaTool logic to SchemaToolService --- .../fdp/uploadschema/SchemaTools.java | 108 +++------------- .../fdp/uploadschema/domain/ResourceTask.java | 27 ---- .../fdp/uploadschema/domain/ShapeTask.java | 51 ++++---- .../uploadschema/integration/FdpClient.java | 4 - .../uploadschema/integration/FdpService.java | 15 ++- .../uploadschema/integration/IFdpClient.java | 15 ++- .../tasks/ResourceUpdateInsertTask.java | 118 ------------------ .../uploadschema/tasks/SchemaToolService.java | 104 ++++++++++++++- .../uploadschema/tasks/ShapeTaskService.java | 59 ++++++++- .../tasks/ShapeUpdateInsertTask.java | 105 ---------------- 10 files changed, 216 insertions(+), 390 deletions(-) delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index 43f56ca..d30129f 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -1,16 +1,13 @@ package nl.healthri.fdp.uploadschema; import com.fasterxml.jackson.databind.ObjectMapper; -import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; import nl.healthri.fdp.uploadschema.integration.FdpClient; import nl.healthri.fdp.uploadschema.integration.FdpService; -import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; -import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; +import nl.healthri.fdp.uploadschema.tasks.ResourceTaskService; +import nl.healthri.fdp.uploadschema.tasks.SchemaToolService; +import nl.healthri.fdp.uploadschema.tasks.ShapeTaskService; import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; -import nl.healthri.fdp.uploadschema.utils.RdfUtils; -import nl.healthri.fdp.uploadschema.utils.XlsToRdfUtils; -import org.eclipse.rdf4j.model.Model; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import picocli.CommandLine; @@ -20,12 +17,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.http.HttpClient; -import java.nio.file.Files; -import java.nio.file.Path; import java.time.Duration; -import java.util.ArrayList; - -import static java.util.function.Predicate.not; @CommandLine.Command(name = "SchemaTools utility that create FDP ready Shacls and upload them the the FDP.", mixinStandardHelpOptions = true, version = "SchemaTool v1.0") @@ -64,105 +56,35 @@ public void run() { .connectTimeout(Duration.ofSeconds(10)) .build(); - ObjectMapper objectMapper = new ObjectMapper(); - FdpClient fdpClient = new FdpClient(client, this.hostname, objectMapper); - + final ObjectMapper objectMapper = new ObjectMapper(); + final FdpClient fdpClient = new FdpClient(client, this.hostname, objectMapper); final FdpService fdpService = new FdpService(fdpClient); final Properties properties = Properties.load(propertyFile); final FileHandler fileHandler = new FileHandler(); + final ResourceTaskService resourceTaskService = new ResourceTaskService(fdpService); + final ShapeTaskService shapeTaskService = new ShapeTaskService(fdpService, fileHandler, properties); + final SchemaToolService schemaToolService = new SchemaToolService(fdpService, resourceTaskService, shapeTaskService, properties, fileHandler); fdpService.authenticate(this.username, this.password); switch (command) { case TEMPLATE -> { - convertTemplatesToShaclShapes(properties); - mergeShapesToFdpSchemas(properties, fileHandler); - mergeShapesForValidation(properties, fileHandler); + schemaToolService.convertTemplatesToShaclShapes(); + schemaToolService.mergeShapesToFdpSchemas(); + schemaToolService.mergeShapesForValidation(); } case BOTH -> { - createOrUpdateSchemas(fdpService, properties, force, fileHandler); - addResourceDescriptions(fdpService, properties); + schemaToolService.createOrUpdateSchemas(force); + schemaToolService.addResourceDescriptions(); } - case SCHEMA -> createOrUpdateSchemas(fdpService, properties, force, fileHandler); - case RESOURCE -> addResourceDescriptions(fdpService, properties); + case SCHEMA -> schemaToolService.createOrUpdateSchemas(force); + case RESOURCE -> schemaToolService.addResourceDescriptions(); } } catch (IOException io) { throw new RuntimeException(io); } } - public void convertTemplatesToShaclShapes(Properties properties) throws IOException { - logger.info("reading templates from {} ", properties.templateDir); - - for (var e : XlsToRdfUtils.getTemplateFiles(properties.templateDir).entrySet()) { - logger.info(" converting {} ", e.getValue()); - Path path = properties.getPiecesDir().resolve(e.getKey() + ".ttl"); - String shacl = XlsToRdfUtils.createShacl(e.getValue()); - Files.write(path, shacl.getBytes()); - } - } - - public void mergeShapesToFdpSchemas(Properties properties, FileHandler rdfUtils) throws IOException { - logger.info("Writing files: {}", properties.getFiles().keySet()); - - for (var e : properties.getFiles(properties.getPiecesDir()).entrySet()) { - Path path = properties.getFairDataPointDir().resolve(RdfUtils.schemaToFilename(e.getKey())); - Model m = rdfUtils.readFiles(e.getValue()); - rdfUtils.safeModel(path, m); - } - } - - public void mergeShapesForValidation(Properties properties, FileHandler rdfUtils) throws IOException { - logger.info("Merging files: {}", properties.getValidationDir()); - - Path path = properties.getValidationDir().resolve("HRI-Datamodel-shapes.ttl"); - logger.info("Write validation file {} combining {} files", path, properties.getAllFiles().size()); - Model m = rdfUtils.readFiles(new ArrayList<>(properties.getAllFiles())); - rdfUtils.safeModel(path, m); - } - - public void createOrUpdateSchemas(FdpService fdpService, Properties properties, boolean force, FileHandler fileHandler) throws IOException { - logger.info("Creating/updating schemas from tasks to FDP"); - - var shapeTasks = ShapeUpdateInsertTask.createTasks(fdpService, properties, fileHandler); - shapeTasks.forEach(task -> { - switch (task.status()) { - case INSERT -> { - fdpService.createSchema(task); - fdpService.releaseSchema(task); - } - case SAME -> { - if (force) { - fdpService.updateSchema(task); - fdpService.releaseSchema(task); - logger.info("Schema {} is updated, it was the same but force was set", task.shape); - } else { - logger.warn("Schema {} is not updated because it's still the same", task.shape); - } - } - case UPDATE -> { - fdpService.updateSchema(task); - fdpService.releaseSchema(task); - } - } - }); - } - - public void addResourceDescriptions(FdpService fdpService, Properties properties) { - logger.info("Adding resource descriptions from resource tasks to FDP"); - - var resourceTasks = ResourceUpdateInsertTask.createTask(properties, fdpService); - resourceTasks.stream().filter(ResourceUpdateInsertTask::isInsert).forEach(fdpService::createResource); - - if (resourceTasks.stream().noneMatch(not(ResourceUpdateInsertTask::isInsert))) { - logger.warn("Updating resources is not supported yet, but will try to add children if needed)"); - } - - //add the previous resources as child to parent. - var resourceTasksParents = ResourceUpdateInsertTask.createParentTask(properties, fdpService); - resourceTasksParents.stream().filter(ResourceUpdateInsertTask::hasChild).forEach(fdpService::updateResource); - } - public enum CommandEnum { SCHEMA, RESOURCE, BOTH, TEMPLATE } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java b/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java index 14cec52..76c58ff 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java @@ -1,12 +1,8 @@ package nl.healthri.fdp.uploadschema.domain; -import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; -import nl.healthri.fdp.uploadschema.utils.ResourceInfo; -import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Map; import java.util.regex.Pattern; public class ResourceTask { @@ -83,17 +79,6 @@ else if (Pattern.matches(".*(s|x|z|ch|sh)$", this.childName)) { } } - public void addShapeUUID(Map fdpSchemaInfoMap, String schema) { - String name = schema.isBlank() ? this.resource : schema; - String fdpSchemaUUID = fdpSchemaInfoMap.get(name).uuid(); - - if (fdpSchemaUUID == null || fdpSchemaUUID.isEmpty()) { - logger.error("Can't find shape: {} ", this.resource); - } - - this.shapeUUUID = fdpSchemaUUID; - } - public String url() { return this.resource.toLowerCase().replaceAll(" ", ""); } @@ -105,16 +90,4 @@ public boolean isInsert() { public boolean hasChild() { return this.childUUuid != null; } - - public void addExistingInfo(Map fdpResourcesMap) { - String uuid = fdpResourcesMap.get(this.resource).uuid(); - if(uuid == null || uuid.isEmpty()) { - logger.warn("Can't find existing info for resource: {} ", this.resource); - } - - this.exists = true; - this.UUID = uuid; - } - - } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java b/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java index 6d46d04..5318cad 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java @@ -2,9 +2,15 @@ import nl.healthri.fdp.uploadschema.Version; import nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus; +import nl.healthri.fdp.uploadschema.utils.SchemaInfo; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; public class ShapeTask { public final String shape; @@ -23,33 +29,28 @@ public ShapeTask(String shape, Version version, String uuid, Set parents this.parents = parents; this.model = model; this.status = status; - - this.validate(); } - public void validate() { - if (shape == null || shape.isEmpty()) { - logger.error("Invalid: shape is required"); - return; - } - if (version == null) { - logger.error("Invalid: version is required"); - return; - } - if (uuid == null || uuid.isEmpty()) { - logger.error("Invalid: uuid is required"); - return; - } - if (model == null || model.isEmpty()) { - logger.error("Invalid: model is required"); - return; - } - if (status == null) { - logger.error("Invalid: status is required"); - return; - } - if (parents == null || parents.isEmpty()) { - logger.error("Invalid: no parents defined for shape '{}'", shape); + public Set getParentUID(Map schemaMap) { + if (this.parents.isEmpty()) { + return Collections.emptySet(); } + + return this.parents.stream() + .map(schemaMap::get) // SchemaInfo + .map(SchemaInfo::uuid) // SchemaInfo.UUID + .collect(Collectors.toSet()); + } + + public String description() { + return shape; + } + + public String url() { + return shape.toLowerCase().replaceAll(" ", ""); + } + + public ShapeStatus status() { + return status; } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java index 6e44995..745aa07 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java @@ -9,11 +9,8 @@ import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; -import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; -import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; import nl.healthri.fdp.uploadschema.utils.HttpRequestUtils; -import org.eclipse.rdf4j.query.Update; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -21,7 +18,6 @@ import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; -import java.net.http.HttpRequest.BodyPublisher; import java.net.http.HttpResponse; import java.util.*; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java index b34e432..9ad2bbc 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java @@ -1,14 +1,14 @@ package nl.healthri.fdp.uploadschema.integration; import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.domain.ResourceTask; +import nl.healthri.fdp.uploadschema.domain.ShapeTask; import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; import nl.healthri.fdp.uploadschema.dto.request.Schema.ReleaseSchemaRequest; import nl.healthri.fdp.uploadschema.dto.request.Schema.UpdateSchemaRequest; import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; -import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; -import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import org.slf4j.Logger; @@ -16,7 +16,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import javax.xml.validation.Schema; import java.util.*; @@ -42,7 +41,7 @@ public List getAllSchemas() { return fdpClient.fetchSchemas(); } - public void createSchema(ShapeUpdateInsertTask task){ + public void createSchema(ShapeTask task){ List schemaDataResponseList = getAllSchemas(); Map schemaInfoMap = new HashMap<>(); @@ -66,7 +65,7 @@ public void createSchema(ShapeUpdateInsertTask task){ } - public void updateSchema(ShapeUpdateInsertTask task){ + public void updateSchema(ShapeTask task){ List schemaDataResponseList = getAllSchemas(); Map schemaInfoMap = new HashMap<>(); @@ -87,7 +86,7 @@ public void updateSchema(ShapeUpdateInsertTask task){ fdpClient.updateSchema(task, updateSchemaRequest); } - public void releaseSchema(ShapeUpdateInsertTask task){ + public void releaseSchema(ShapeTask task){ ReleaseSchemaRequest releaseSchemaRequest = ReleaseSchemaRequest.of(task.shape, false, task.version); fdpClient.releaseSchema(task, releaseSchemaRequest); @@ -97,7 +96,7 @@ public List getAllResources() { return fdpClient.fetchResources(); } - public void createResource(ResourceUpdateInsertTask task){ + public void createResource(ResourceTask task){ ResourceRequest resourceRequest = new ResourceRequest( task.resource, task.url(), @@ -110,7 +109,7 @@ public void createResource(ResourceUpdateInsertTask task){ task.UUID = resourceResponse.uuid(); } - public void updateResource(ResourceUpdateInsertTask task){ + public void updateResource(ResourceTask task){ ResourceResponse resourceResponse = fdpClient.fetchResource(task.UUID); if (resourceResponse.children().stream().anyMatch(c -> c.resourceDefinitionUuid().equals(task.childUUuid))) { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java index 9628aba..43351fa 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java @@ -1,16 +1,15 @@ package nl.healthri.fdp.uploadschema.integration; +import nl.healthri.fdp.uploadschema.domain.ResourceTask; +import nl.healthri.fdp.uploadschema.domain.ShapeTask; import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; import nl.healthri.fdp.uploadschema.dto.request.Schema.ReleaseSchemaRequest; import nl.healthri.fdp.uploadschema.dto.request.Schema.UpdateSchemaRequest; import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; -import nl.healthri.fdp.uploadschema.tasks.ResourceUpdateInsertTask; -import nl.healthri.fdp.uploadschema.tasks.ShapeUpdateInsertTask; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; -import java.net.http.HttpRequest; import java.util.List; public interface IFdpClient { @@ -18,12 +17,12 @@ public interface IFdpClient { LoginResponse getAuthToken(LoginRequest loginRequest); List fetchSchemas(); - ResourceResponse insertSchema(ShapeUpdateInsertTask task, UpdateSchemaRequest updateSchemaRequest); - void updateSchema(ShapeUpdateInsertTask task, UpdateSchemaRequest updateSchemaRequest); - void releaseSchema(ShapeUpdateInsertTask task, ReleaseSchemaRequest releaseSchemaRequest); + ResourceResponse insertSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest); + void updateSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest); + void releaseSchema(ShapeTask task, ReleaseSchemaRequest releaseSchemaRequest); List fetchResources(); ResourceResponse fetchResource(String resourceId); - ResourceResponse insertResource(ResourceUpdateInsertTask task, ResourceRequest resourceRequest ); - void updateResource(ResourceUpdateInsertTask task, ResourceResponse resourceResponse); + ResourceResponse insertResource(ResourceTask task, ResourceRequest resourceRequest ); + void updateResource(ResourceTask task, ResourceResponse resourceResponse); } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java deleted file mode 100644 index 3ec69a2..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceUpdateInsertTask.java +++ /dev/null @@ -1,118 +0,0 @@ -package nl.healthri.fdp.uploadschema.tasks; - -import nl.healthri.fdp.uploadschema.Version; -import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.integration.FdpService; -import nl.healthri.fdp.uploadschema.utils.Properties; -import nl.healthri.fdp.uploadschema.utils.ResourceInfo; -import nl.healthri.fdp.uploadschema.utils.SchemaInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; - -public class ResourceUpdateInsertTask { - - private static final Logger logger = LoggerFactory.getLogger(ResourceUpdateInsertTask.class); - - public final String resource; - public String UUID; - public String shapeUUUID; - public String childUUuid; - public String childRelationIri; - public String childName; - boolean exists = false; - - public ResourceUpdateInsertTask(String resource) { - this.resource = resource; - } - - // todo: Map - // todo: Map - public static List createParentTask(Properties p, FdpService fdpService) { - - List resourceResponseList = fdpService.getAllResources(); - - Map fdpResourceMap = new HashMap<>(); - for(ResourceResponse resourceResponse : resourceResponseList) { - ResourceInfo resourceInfo = new ResourceInfo(resourceResponse.name(), resourceResponse.uuid()); - fdpResourceMap.put(resourceResponse.name(), resourceInfo); - } - - - return p.resources.entrySet().stream().map(r -> { - //now we to update the parent not the resource itself! - var parentName = r.getValue().parentResource(); - var childName = r.getKey(); - var childIri = r.getValue().parentRelationIri(); - - return new ResourceUpdateInsertTask(parentName) - .addExistingInfo(fdpResourceMap) //adds uuid - .addChildInfo(childName, childIri, fdpResourceMap); - }).toList(); - } - - public ResourceUpdateInsertTask addExistingInfo(Map fdpResourcesMap) { - String uuid = fdpResourcesMap.get(this.resource).uuid(); - if(uuid == null || uuid.isEmpty()) { - logger.warn("Can't find existing info for resource: {} ", this.resource); - } - - this.exists = true; - this.UUID = uuid; - return this; -} - - public ResourceUpdateInsertTask addChildInfo(String name, String relationIri, Map fdpResourcesMap) { - String uuid = fdpResourcesMap.get(this.resource).uuid(); - if(uuid == null || uuid.isEmpty()) { - logger.error("Child resource is not found {} ", name); - return this; - } - - this.childUUuid = uuid; - this.childRelationIri = relationIri; - this.childName = name; - return this; - } - - - - - public String pluralName() { - //FIXME shape datasetSeries is already plural form. - if (childName.toLowerCase().endsWith("ies")) return childName; - - // Rule 1: Words ending in consonant + "y" -> replace "y" with "ies" - if (Pattern.matches(".*[^aeiou]y$", childName)) { - return childName.replaceAll("y$", "ies"); - } - // Rule 2: Words ending in "s", "x", "z", "ch", or "sh" -> add "es" - else if (Pattern.matches(".*(s|x|z|ch|sh)$", childName)) { - return childName + "es"; - } - // Default rule: Just add "s" - else { - return childName + "s"; - } - } - - - - public String url() { - return resource.toLowerCase().replaceAll(" ", ""); - } - - public boolean isInsert() { - return !exists; - } - - public boolean hasChild() { - return childUUuid != null; - } - -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java index 45b9187..c2bb292 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java @@ -1,11 +1,113 @@ package nl.healthri.fdp.uploadschema.tasks; +import nl.healthri.fdp.uploadschema.domain.ResourceTask; +import nl.healthri.fdp.uploadschema.domain.ShapeTask; import nl.healthri.fdp.uploadschema.integration.FdpService; +import nl.healthri.fdp.uploadschema.utils.FileHandler; +import nl.healthri.fdp.uploadschema.utils.Properties; +import nl.healthri.fdp.uploadschema.utils.RdfUtils; +import nl.healthri.fdp.uploadschema.utils.XlsToRdfUtils; +import org.eclipse.rdf4j.model.Model; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.awt.*; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import static java.util.function.Predicate.not; +import static nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus.*; public class SchemaToolService { - public SchemaToolService() { + public FdpService fdpService; + public ResourceTaskService resourceTaskService; + public ShapeTaskService shapeTaskService; + public Properties properties; + public FileHandler fileHandler; + + private static final Logger logger = LoggerFactory.getLogger(SchemaToolService.class); + + public SchemaToolService(FdpService fdpService, ResourceTaskService resourceTaskService, ShapeTaskService shapeTaskService, Properties properties, FileHandler fileHandler) { + this.fdpService = fdpService; + this.resourceTaskService = resourceTaskService; + this.shapeTaskService = shapeTaskService; + this.properties = properties; + this.fileHandler = fileHandler; + } + public void createOrUpdateSchemas(boolean force) throws IOException { + logger.info("Creating/updating schemas from tasks to FDP"); + + List shapeTaskList = shapeTaskService.createTasks(); + shapeTaskList.forEach(task -> { + switch (task.status()) { + case INSERT -> { + fdpService.createSchema(task); + fdpService.releaseSchema(task); + } + case SAME -> { + if (force) { + fdpService.updateSchema(task); + fdpService.releaseSchema(task); + logger.info("Schema {} is updated, it was the same but force was set", task.shape); + } else { + logger.warn("Schema {} is not updated because it's still the same", task.shape); + } + } + case UPDATE -> { + fdpService.updateSchema(task); + fdpService.releaseSchema(task); + } + } + }); } + public void convertTemplatesToShaclShapes() throws IOException { + logger.info("reading templates from {} ", properties.templateDir); + + for (var e : XlsToRdfUtils.getTemplateFiles(properties.templateDir).entrySet()) { + logger.info(" converting {} ", e.getValue()); + Path path = properties.getPiecesDir().resolve(e.getKey() + ".ttl"); + String shacl = XlsToRdfUtils.createShacl(e.getValue()); + Files.write(path, shacl.getBytes()); + } + } + + public void mergeShapesToFdpSchemas() throws IOException { + logger.info("Writing files: {}", properties.getFiles().keySet()); + + for (var e : properties.getFiles(properties.getPiecesDir()).entrySet()) { + Path path = properties.getFairDataPointDir().resolve(RdfUtils.schemaToFilename(e.getKey())); + Model m = fileHandler.readFiles(e.getValue()); + fileHandler.safeModel(path, m); + } + } + + public void mergeShapesForValidation() throws IOException { + logger.info("Merging files: {}", properties.getValidationDir()); + + Path path = properties.getValidationDir().resolve("HRI-Datamodel-shapes.ttl"); + logger.info("Write validation file {} combining {} files", path, properties.getAllFiles().size()); + Model m = fileHandler.readFiles(new ArrayList<>(properties.getAllFiles())); + fileHandler.safeModel(path, m); + } + + public void addResourceDescriptions() { + logger.info("Adding resource descriptions from resource tasks to FDP"); + + List resourceTaskList = this.resourceTaskService.createTasks(); + resourceTaskList.stream().filter(ResourceTask::isInsert).forEach(this.fdpService::createResource); + + if (resourceTaskList.stream().noneMatch(not(ResourceTask::isInsert))) { + logger.warn("Updating resources is not supported yet, but will try to add children if needed)"); + } + + //add the previous resources as child to parent. + List resourceTasksParents = resourceTaskService.createParentTasks(); + resourceTasksParents.stream().filter(ResourceTask::hasChild).forEach(fdpService::updateResource); + } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java index fc6799a..5ce0414 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java @@ -1,12 +1,30 @@ package nl.healthri.fdp.uploadschema.tasks; +import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.domain.ResourceTask; +import nl.healthri.fdp.uploadschema.domain.ShapeTask; +import nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus; +import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.integration.FdpClient; import nl.healthri.fdp.uploadschema.integration.FdpService; -import nl.healthri.fdp.uploadschema.utils.FileHandler; +import nl.healthri.fdp.uploadschema.utils.*; import nl.healthri.fdp.uploadschema.utils.Properties; +import org.eclipse.rdf4j.model.Model; +import org.eclipse.rdf4j.model.util.Models; +import org.eclipse.rdf4j.query.algebra.Str; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.awt.*; +import java.net.URI; +import java.util.*; +import java.util.List; +import java.util.stream.Collectors; + +import static nl.healthri.fdp.uploadschema.utils.ResourceInfo.createResourceInfoMap; +import static nl.healthri.fdp.uploadschema.utils.SchemaInfo.createSchemaInfoMap; + public class ShapeTaskService { public FdpService fdpService; public FileHandler fileHandler; @@ -20,6 +38,45 @@ public ShapeTaskService(FdpService fdpService, FileHandler fileHandler, Properti this.properties = properties; } + public List createTasks() { + Map> files = this.properties.getFiles(); + List schemaDataResponseList = this.fdpService.getAllSchemas(); + Map schemaInfoMap = createSchemaInfoMap(schemaDataResponseList); + + //list of the task we have to do for insert/updating shacls + return this.properties.schemasToPublish.stream().map(schemaTitle -> { + List ttlFiles = Optional.ofNullable(files.get(schemaTitle)).orElseThrow(() -> new NoSuchElementException(schemaTitle + " not present in schema section of yaml-file")); + Model newModel = fileHandler.readFiles(ttlFiles); + String model = RdfUtils.modelAsTurtleString(newModel); + Version requestedVersion = this.properties.getVersion(); + Set parents = this.properties.getParents(schemaTitle); + if (schemaInfoMap.containsKey(schemaTitle)) { + SchemaInfo matchingFdpSchema = schemaInfoMap.get(schemaTitle); + Version version = matchingFdpSchema.version().next(requestedVersion); + String uuid = matchingFdpSchema.uuid(); + Model fdpSchemaModel = RdfUtils.fromTurtleString(matchingFdpSchema.definition()); + ShapeStatus status = Models.isomorphic(fdpSchemaModel, newModel) ? ShapeStatus.SAME : ShapeStatus.UPDATE; + + return new ShapeTask( + schemaTitle, + version, + uuid, + parents, + model, + status + ); + } else { + return new ShapeTask( + schemaTitle, + requestedVersion, + "", + parents, + model, + ShapeStatus.INSERT + ); + } + }).toList(); + } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java deleted file mode 100644 index 9bc3a87..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTask.java +++ /dev/null @@ -1,105 +0,0 @@ -package nl.healthri.fdp.uploadschema.tasks; - -import nl.healthri.fdp.uploadschema.Version; -import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.integration.FdpService; -import nl.healthri.fdp.uploadschema.utils.*; -import nl.healthri.fdp.uploadschema.utils.Properties; -import org.eclipse.rdf4j.model.Model; -import org.eclipse.rdf4j.model.impl.LinkedHashModel; -import org.eclipse.rdf4j.model.util.Models; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.xml.validation.Schema; -import java.net.URI; -import java.net.URL; -import java.util.*; -import java.util.stream.Collectors; - -public class ShapeUpdateInsertTask { - private static final Logger logger = LoggerFactory.getLogger(ShapeUpdateInsertTask.class); - - - - public ShapeUpdateInsertTask(String shape) { - this.shape = shape; - } - - public static List createTasks(FdpService fdpService, Properties p, FileHandler fileHandler){ - final List schemaList = p.schemasToPublish; - final Map> files = p.getFiles(); - - final List schemaDataResponseList = fdpService.getAllSchemas(); - - Map schemaInfoMap = new HashMap<>(); - for(SchemaDataResponse schemaDataResponse : schemaDataResponseList) { - Version version = new Version(schemaDataResponse.latest().version()); - SchemaInfo schemaInfo = new SchemaInfo( - version, - schemaDataResponse.uuid(), - schemaDataResponse.latest().definition()); - schemaInfoMap.put(schemaDataResponse.name(), schemaInfo); - } - - logger.info("found following shapes on fdp: {}", schemaInfoMap.keySet()); - - //list of the task we have to do for insert/updating shacls - return schemaList.stream().map(schemaTitle -> { - ShapeUpdateInsertTask shapeUpdateInsertTask = new ShapeUpdateInsertTask(schemaTitle); - Version requestedVersion = p.getVersion(); - var ttlFiles = Optional.ofNullable(files.get(schemaTitle)).orElseThrow(() -> new NoSuchElementException(schemaTitle + " not present in schema section of yaml-file")); - - logger.debug("loading model {} using turtle files: {} ", schemaTitle, ttlFiles.stream().map(URI::toString).collect(Collectors.joining(", "))); - - Model newModel = fileHandler.readFiles(ttlFiles); - shapeUpdateInsertTask.model = RdfUtils.modelAsTurtleString(newModel); - - if (schemaInfoMap.containsKey(schemaTitle)) { - // Gets matching schema title from map - SchemaInfo matchingFdpSchema = schemaInfoMap.get(schemaTitle); - - // Gets schema model as .ttl format - Model fdpSchemaModel = RdfUtils.fromTurtleString(matchingFdpSchema.definition()); - - // Sets task variables - shapeUpdateInsertTask.version = matchingFdpSchema.version().next(requestedVersion); - shapeUpdateInsertTask.uuid = matchingFdpSchema.uuid(); - shapeUpdateInsertTask.status = Models.isomorphic(fdpSchemaModel, newModel) ? ShapeStatus.SAME : ShapeStatus.UPDATE; - } else { - - shapeUpdateInsertTask.version = requestedVersion; - shapeUpdateInsertTask.uuid = ""; - shapeUpdateInsertTask.status = ShapeStatus.INSERT; - } - - shapeUpdateInsertTask.parents = p.getParents(schemaTitle); - return shapeUpdateInsertTask; - }).toList(); - } - - public Set getParentUID(Map schemaMap) { - if (this.parents.isEmpty()) { - return Collections.emptySet(); - } - - return this.parents.stream() - .map(schemaMap::get) // SchemaInfo - .map(SchemaInfo::uuid) // SchemaInfo.UUID - .collect(Collectors.toSet()); - } - - public String description() { - return shape; - } - - public String url() { - return shape.toLowerCase().replaceAll(" ", ""); - } - - public ShapeStatus status() { - return status; - } -} - From 852aeb85e6515f7fbf9dd2ad4cb2235ed98d7b08 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Tue, 4 Nov 2025 10:02:44 +0100 Subject: [PATCH 18/51] refactor: Added interfaces --- .../healthri/fdp/uploadschema/SchemaTools.java | 2 +- .../fdp/uploadschema/integration/FdpClient.java | 16 +++++++++------- .../{IFdpClient.java => FdpClientInterface.java} | 2 +- .../fdp/uploadschema/integration/FdpService.java | 4 ++-- .../uploadschema/tasks/ResourceTaskService.java | 5 +++-- .../tasks/ResourceTaskServiceInterface.java | 10 ++++++++++ .../uploadschema/tasks/SchemaToolService.java | 8 ++++---- .../tasks/SchemaToolServiceInterface.java | 11 +++++++++++ .../fdp/uploadschema/tasks/ShapeTaskService.java | 2 +- .../tasks/ShapeTaskServiceInterface.java | 9 +++++++++ 10 files changed, 51 insertions(+), 18 deletions(-) rename src/main/java/nl/healthri/fdp/uploadschema/integration/{IFdpClient.java => FdpClientInterface.java} (97%) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskServiceInterface.java create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolServiceInterface.java create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskServiceInterface.java diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index d30129f..2c3fb33 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -61,7 +61,7 @@ public void run() { final FdpService fdpService = new FdpService(fdpClient); final Properties properties = Properties.load(propertyFile); final FileHandler fileHandler = new FileHandler(); - final ResourceTaskService resourceTaskService = new ResourceTaskService(fdpService); + final ResourceTaskService resourceTaskService = new ResourceTaskService(fdpService, properties); final ShapeTaskService shapeTaskService = new ShapeTaskService(fdpService, fileHandler, properties); final SchemaToolService schemaToolService = new SchemaToolService(fdpService, resourceTaskService, shapeTaskService, properties, fileHandler); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java index 745aa07..86c28c3 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java @@ -2,6 +2,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import nl.healthri.fdp.uploadschema.domain.ResourceTask; +import nl.healthri.fdp.uploadschema.domain.ShapeTask; import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; import nl.healthri.fdp.uploadschema.dto.request.Schema.ReleaseSchemaRequest; import nl.healthri.fdp.uploadschema.dto.request.Schema.UpdateSchemaRequest; @@ -25,7 +27,7 @@ // TODO: Throw client exception instead of Runtimeexception (otherwise you hide the error encountered) @Component -public class FdpClient implements IFdpClient { +public class FdpClient implements FdpClientInterface { private final HttpClient client; private final URI hostname; private final ObjectMapper objectMapper; @@ -114,7 +116,7 @@ public List fetchSchemas() { * @param task task, with info about the shape to create, * when the shapes are created it will update this parameter by setting the UUID! */ - public ResourceResponse insertSchema(ShapeUpdateInsertTask task, UpdateSchemaRequest updateSchemaRequest) { + public ResourceResponse insertSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest) { logger.info("Inserting {} schema into FDP", task.shape); try { @@ -150,7 +152,7 @@ public ResourceResponse insertSchema(ShapeUpdateInsertTask task, UpdateSchemaReq - public void updateSchema(ShapeUpdateInsertTask task, UpdateSchemaRequest updateSchemaRequest) { + public void updateSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest) { logger.info("Updating shape {} in FDP", task.shape); try { @@ -180,7 +182,7 @@ public void updateSchema(ShapeUpdateInsertTask task, UpdateSchemaRequest updateS } } - public void releaseSchema(ShapeUpdateInsertTask task, ReleaseSchemaRequest releaseSchemaRequest) { + public void releaseSchema(ShapeTask task, ReleaseSchemaRequest releaseSchemaRequest) { logger.info("Releasing {} into FDP", task.shape); try { @@ -234,7 +236,7 @@ public List fetchResources() { HttpRequestUtils.handleResponseStatus(response); // Map response to body - return List.of(objectMapper.readValue(response.body(), ResourceResponse.class)); + return List.of(objectMapper.readValue(response.body(), ResourceResponse[].class)); } catch (Exception e) { throw new RuntimeException(e); } @@ -269,7 +271,7 @@ public ResourceResponse fetchResource(String resourceId){ } } - public ResourceResponse insertResource(ResourceUpdateInsertTask task, ResourceRequest resourceRequest) { + public ResourceResponse insertResource(ResourceTask task, ResourceRequest resourceRequest) { logger.info("Inserting {} resources into FDP", task.resource); try { @@ -304,7 +306,7 @@ public ResourceResponse insertResource(ResourceUpdateInsertTask task, ResourceRe } } - public void updateResource(ResourceUpdateInsertTask task, ResourceResponse resourceResponse) { + public void updateResource(ResourceTask task, ResourceResponse resourceResponse) { logger.info("updating resource {} in FDP", task.resource); try { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClientInterface.java similarity index 97% rename from src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java rename to src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClientInterface.java index 43351fa..0498825 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/IFdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClientInterface.java @@ -12,7 +12,7 @@ import java.util.List; -public interface IFdpClient { +public interface FdpClientInterface { void setAuthToken(LoginResponse loginResponse); LoginResponse getAuthToken(LoginRequest loginRequest); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java index 9ad2bbc..076c09f 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java @@ -21,12 +21,12 @@ @Service public class FdpService { - private final IFdpClient fdpClient; + private final FdpClientInterface fdpClient; private static final Logger logger = LoggerFactory.getLogger(FdpService.class); @Autowired - public FdpService(IFdpClient fdpClient) { + public FdpService(FdpClientInterface fdpClient) { this.fdpClient = fdpClient; } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java index e2c88f6..7d01881 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java @@ -19,14 +19,15 @@ import static nl.healthri.fdp.uploadschema.utils.ResourceInfo.createResourceInfoMap; import static nl.healthri.fdp.uploadschema.utils.SchemaInfo.createSchemaInfoMap; -public class ResourceTaskService { +public class ResourceTaskService implements ResourceTaskServiceInterface { public FdpService fdpService; public Properties properties; private static final Logger logger = LoggerFactory.getLogger(ResourceTaskService.class); - public ResourceTaskService(FdpService fdpService) { + public ResourceTaskService(FdpService fdpService, Properties properties) { this.fdpService = fdpService; + this.properties = properties; } public List createTasks() { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskServiceInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskServiceInterface.java new file mode 100644 index 0000000..2bdd5df --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskServiceInterface.java @@ -0,0 +1,10 @@ +package nl.healthri.fdp.uploadschema.tasks; + +import nl.healthri.fdp.uploadschema.domain.ResourceTask; + +import java.util.List; + +public interface ResourceTaskServiceInterface { + List createTasks(); + List createParentTasks(); +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java index c2bb292..9e6fd07 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java @@ -21,16 +21,16 @@ import static java.util.function.Predicate.not; import static nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus.*; -public class SchemaToolService { +public class SchemaToolService implements SchemaToolServiceInterface { public FdpService fdpService; - public ResourceTaskService resourceTaskService; - public ShapeTaskService shapeTaskService; + public ResourceTaskServiceInterface resourceTaskService; + public ShapeTaskServiceInterface shapeTaskService; public Properties properties; public FileHandler fileHandler; private static final Logger logger = LoggerFactory.getLogger(SchemaToolService.class); - public SchemaToolService(FdpService fdpService, ResourceTaskService resourceTaskService, ShapeTaskService shapeTaskService, Properties properties, FileHandler fileHandler) { + public SchemaToolService(FdpService fdpService, ResourceTaskServiceInterface resourceTaskService, ShapeTaskServiceInterface shapeTaskService, Properties properties, FileHandler fileHandler) { this.fdpService = fdpService; this.resourceTaskService = resourceTaskService; this.shapeTaskService = shapeTaskService; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolServiceInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolServiceInterface.java new file mode 100644 index 0000000..b1c837f --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolServiceInterface.java @@ -0,0 +1,11 @@ +package nl.healthri.fdp.uploadschema.tasks; + +import java.io.IOException; + +public interface SchemaToolServiceInterface { + void createOrUpdateSchemas(boolean force) throws IOException; + void convertTemplatesToShaclShapes() throws IOException; + void mergeShapesToFdpSchemas() throws IOException; + void mergeShapesForValidation() throws IOException; + void addResourceDescriptions(); +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java index 5ce0414..4b11840 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java @@ -25,7 +25,7 @@ import static nl.healthri.fdp.uploadschema.utils.ResourceInfo.createResourceInfoMap; import static nl.healthri.fdp.uploadschema.utils.SchemaInfo.createSchemaInfoMap; -public class ShapeTaskService { +public class ShapeTaskService implements ShapeTaskServiceInterface { public FdpService fdpService; public FileHandler fileHandler; public Properties properties; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskServiceInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskServiceInterface.java new file mode 100644 index 0000000..f40683d --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskServiceInterface.java @@ -0,0 +1,9 @@ +package nl.healthri.fdp.uploadschema.tasks; + +import nl.healthri.fdp.uploadschema.domain.ShapeTask; + +import java.util.List; + +public interface ShapeTaskServiceInterface { + List createTasks(); +} From f47ca5213bc208bcdf976c6af48276329f322324 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Tue, 4 Nov 2025 13:32:43 +0100 Subject: [PATCH 19/51] refactor: added handler for createTask null on map search handling --- .../fdp/uploadschema/domain/ResourceTask.java | 13 +---- .../uploadschema/integration/FdpClient.java | 1 - .../tasks/ResourceTaskService.java | 56 +++++++++++-------- .../uploadschema/tasks/ShapeTaskService.java | 6 -- 4 files changed, 35 insertions(+), 41 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java b/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java index 76c58ff..b2018c7 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java @@ -17,22 +17,13 @@ public class ResourceTask { private static final Logger logger = LoggerFactory.getLogger(ResourceTask.class); - public ResourceTask(String resource, String uuid, String shapeUUUID) { + public ResourceTask(String resource, String uuid, String shapeUUUID, boolean exists) { this.resource = resource; this.UUID = uuid; this.shapeUUUID = shapeUUUID; - this.exists = false; + this.exists = exists; } - public ResourceTask(String resource, String uuid, String shapeUUUID, String childUUUID, String childRelationIri, String childName) { - this.resource = resource; - this.UUID = uuid; - this.shapeUUUID = shapeUUUID; - this.childUUuid = childUUUID; - this.childRelationIri = childRelationIri; - this.childName = childName; - this.exists = false; - } public void addChildInfo(String childUUuid, String childRelationIri, String childName) { this.childUUuid = childUUuid; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java index 86c28c3..df5feee 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java @@ -283,7 +283,6 @@ public ResourceResponse insertResource(ResourceTask task, ResourceRequest resour this.objectMapper.writeValueAsString(resourceRequest) ); - // Creates request HttpRequest request = HttpRequest.newBuilder() .POST(body) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java index 7d01881..b45e169 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java @@ -40,20 +40,25 @@ public List createTasks() { // Build and validate ResourceTasks return properties.resources.entrySet().stream().map(entry -> { - String resource = entry.getKey(); + String resourceName = entry.getKey(); + String resourceUuid = ""; + boolean exists = false; - // Gets resource id - String resourceUuid = resourceInfoMap.get(resource).uuid(); + ResourceInfo fdpResourceInfo = resourceInfoMap.get(resourceName); + if(fdpResourceInfo != null){ + resourceUuid = fdpResourceInfo.uuid(); + exists = true; + } - // Get schema id String schema = entry.getValue().schema(); - String name = schema.isBlank() ? resource : schema; + String name = schema.isBlank() ? resourceName : schema; String schemaUUID = schemaInfoMap.get(name).uuid(); return new ResourceTask( - resource, + resourceName, resourceUuid, - schemaUUID + schemaUUID, + exists ); }).toList(); } @@ -63,24 +68,29 @@ public List createParentTasks() { Map resourceInfoMap = createResourceInfoMap(resourceResponseList); return this.properties.resources.entrySet().stream().map(entry -> { - String parentName = entry.getValue().parentResource(); - - // Gets resource id - String resourceUuid = resourceInfoMap.get(parentName).uuid(); - - // Get child attributes - String childName = entry.getKey(); - String childIri = entry.getValue().parentRelationIri(); - String childUuid = resourceInfoMap.get(parentName).uuid(); - - return new ResourceTask( - parentName, - resourceUuid, + String parentResourceName = entry.getValue().parentResource(); + String parentResourceUuid = ""; + String childName = ""; + String childIri = ""; + String childUuid = ""; + boolean exists = false; + + ResourceInfo fdpResourceInfo = resourceInfoMap.get(parentResourceName); + if(fdpResourceInfo != null){ + parentResourceUuid = fdpResourceInfo.uuid(); + childName = entry.getKey(); + childIri = entry.getValue().parentRelationIri(); + childUuid = resourceInfoMap.get(parentResourceName).uuid(); + } + + ResourceTask resourceTask = new ResourceTask( + parentResourceName, + parentResourceUuid, null, - childUuid, - childIri, - childName + exists ); + resourceTask.addChildInfo(childUuid, childIri, childName); + return resourceTask; }).toList(); } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java index 4b11840..b6075b8 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java @@ -1,18 +1,14 @@ package nl.healthri.fdp.uploadschema.tasks; import nl.healthri.fdp.uploadschema.Version; -import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; import nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus; -import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.integration.FdpClient; import nl.healthri.fdp.uploadschema.integration.FdpService; import nl.healthri.fdp.uploadschema.utils.*; import nl.healthri.fdp.uploadschema.utils.Properties; import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.model.util.Models; -import org.eclipse.rdf4j.query.algebra.Str; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,9 +16,7 @@ import java.net.URI; import java.util.*; import java.util.List; -import java.util.stream.Collectors; -import static nl.healthri.fdp.uploadschema.utils.ResourceInfo.createResourceInfoMap; import static nl.healthri.fdp.uploadschema.utils.SchemaInfo.createSchemaInfoMap; public class ShapeTaskService implements ShapeTaskServiceInterface { From 95f0477c82bec1ee703564372254f969ba8d1458 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Tue, 4 Nov 2025 13:43:47 +0100 Subject: [PATCH 20/51] refactor: moved Version.java and removed unused imports and whitespaces --- src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java | 6 +++--- .../java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java | 1 - .../nl/healthri/fdp/uploadschema/{ => domain}/Version.java | 2 +- .../dto/request/Schema/ReleaseSchemaRequest.java | 2 +- .../healthri/fdp/uploadschema/integration/FdpService.java | 2 +- .../{tasks => services}/ResourceTaskService.java | 5 +---- .../{tasks => services}/ResourceTaskServiceInterface.java | 2 +- .../uploadschema/{tasks => services}/SchemaToolService.java | 4 +--- .../{tasks => services}/SchemaToolServiceInterface.java | 2 +- .../uploadschema/{tasks => services}/ShapeTaskService.java | 5 ++--- .../{tasks => services}/ShapeTaskServiceInterface.java | 2 +- .../nl/healthri/fdp/uploadschema/utils/FileHandler.java | 3 --- .../java/nl/healthri/fdp/uploadschema/utils/Properties.java | 3 +-- .../java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java | 1 - .../nl/healthri/fdp/uploadschema/utils/ResourceInfo.java | 1 - .../java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java | 3 +-- .../{tasks => services}/ShapeUpdateInsertTaskTest.java | 4 ++-- .../nl/healthri/fdp/uploadschema/utils/VersionTest.java | 2 +- 18 files changed, 18 insertions(+), 32 deletions(-) rename src/main/java/nl/healthri/fdp/uploadschema/{ => domain}/Version.java (97%) rename src/main/java/nl/healthri/fdp/uploadschema/{tasks => services}/ResourceTaskService.java (95%) rename src/main/java/nl/healthri/fdp/uploadschema/{tasks => services}/ResourceTaskServiceInterface.java (82%) rename src/main/java/nl/healthri/fdp/uploadschema/{tasks => services}/SchemaToolService.java (97%) rename src/main/java/nl/healthri/fdp/uploadschema/{tasks => services}/SchemaToolServiceInterface.java (88%) rename src/main/java/nl/healthri/fdp/uploadschema/{tasks => services}/ShapeTaskService.java (96%) rename src/main/java/nl/healthri/fdp/uploadschema/{tasks => services}/ShapeTaskServiceInterface.java (77%) rename src/test/java/nl/healthri/fdp/uploadschema/{tasks => services}/ShapeUpdateInsertTaskTest.java (98%) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index 2c3fb33..f4497f5 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -3,9 +3,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import nl.healthri.fdp.uploadschema.integration.FdpClient; import nl.healthri.fdp.uploadschema.integration.FdpService; -import nl.healthri.fdp.uploadschema.tasks.ResourceTaskService; -import nl.healthri.fdp.uploadschema.tasks.SchemaToolService; -import nl.healthri.fdp.uploadschema.tasks.ShapeTaskService; +import nl.healthri.fdp.uploadschema.services.ResourceTaskService; +import nl.healthri.fdp.uploadschema.services.SchemaToolService; +import nl.healthri.fdp.uploadschema.services.ShapeTaskService; import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; import org.slf4j.Logger; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java b/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java index 5318cad..93d1d8c 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/domain/ShapeTask.java @@ -1,6 +1,5 @@ package nl.healthri.fdp.uploadschema.domain; -import nl.healthri.fdp.uploadschema.Version; import nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/Version.java b/src/main/java/nl/healthri/fdp/uploadschema/domain/Version.java similarity index 97% rename from src/main/java/nl/healthri/fdp/uploadschema/Version.java rename to src/main/java/nl/healthri/fdp/uploadschema/domain/Version.java index f267ee2..787d9a9 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/Version.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/domain/Version.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema; +package nl.healthri.fdp.uploadschema.domain; import java.util.Comparator; import java.util.Objects; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/ReleaseSchemaRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/ReleaseSchemaRequest.java index 7fc25f0..492d1a0 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/ReleaseSchemaRequest.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/ReleaseSchemaRequest.java @@ -2,7 +2,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.domain.Version; public record ReleaseSchemaRequest( @JsonProperty("description") diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java index 076c09f..a1bea26 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java @@ -1,6 +1,6 @@ package nl.healthri.fdp.uploadschema.integration; -import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java similarity index 95% rename from src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java rename to src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index b45e169..b3fea25 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -1,6 +1,5 @@ -package nl.healthri.fdp.uploadschema.tasks; +package nl.healthri.fdp.uploadschema.services; -import nl.healthri.fdp.uploadschema.Version; import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; @@ -11,11 +10,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.HashMap; import java.util.List; import java.util.Map; -import static java.util.stream.Collectors.toList; import static nl.healthri.fdp.uploadschema.utils.ResourceInfo.createResourceInfoMap; import static nl.healthri.fdp.uploadschema.utils.SchemaInfo.createSchemaInfoMap; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskServiceInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceInterface.java similarity index 82% rename from src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskServiceInterface.java rename to src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceInterface.java index 2bdd5df..a3280b9 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ResourceTaskServiceInterface.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceInterface.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.tasks; +package nl.healthri.fdp.uploadschema.services; import nl.healthri.fdp.uploadschema.domain.ResourceTask; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java similarity index 97% rename from src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java rename to src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java index 9e6fd07..6ebb283 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.tasks; +package nl.healthri.fdp.uploadschema.services; import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; @@ -11,7 +11,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.awt.*; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -19,7 +18,6 @@ import java.util.List; import static java.util.function.Predicate.not; -import static nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus.*; public class SchemaToolService implements SchemaToolServiceInterface { public FdpService fdpService; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolServiceInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolServiceInterface.java similarity index 88% rename from src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolServiceInterface.java rename to src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolServiceInterface.java index b1c837f..8774eb7 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/SchemaToolServiceInterface.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolServiceInterface.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.tasks; +package nl.healthri.fdp.uploadschema.services; import java.io.IOException; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java similarity index 96% rename from src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java rename to src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java index b6075b8..b8264bf 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java @@ -1,6 +1,6 @@ -package nl.healthri.fdp.uploadschema.tasks; +package nl.healthri.fdp.uploadschema.services; -import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.domain.ShapeTask; import nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; @@ -12,7 +12,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.awt.*; import java.net.URI; import java.util.*; import java.util.List; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskServiceInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceInterface.java similarity index 77% rename from src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskServiceInterface.java rename to src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceInterface.java index f40683d..a16cffd 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/tasks/ShapeTaskServiceInterface.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceInterface.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.tasks; +package nl.healthri.fdp.uploadschema.services; import nl.healthri.fdp.uploadschema.domain.ShapeTask; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java index 05078dc..e414a4f 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java @@ -82,7 +82,6 @@ private void readFile(URI uri, RDFParser parser) throws IOException { } private InputStream getInputStream(URI uri) throws IOException { - if (List.of("http", "https").contains(uri.getScheme().toLowerCase())) { logger.trace("Fetch from github: {}", uri); try (HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(5)).followRedirects(HttpClient.Redirect.NORMAL).build()) { @@ -124,6 +123,4 @@ private void validateNamespaces(Model model) { logger.warn("Duplicate namespace found."); } } - - } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java index 214688f..98b0327 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.databind.DatabindException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.domain.Version; import java.io.File; import java.io.FileNotFoundException; @@ -183,6 +183,5 @@ public Set getParents(String child) { .filter(e -> e.getValue().contains(child)) .map(Map.Entry::getKey).collect(Collectors.toSet()); } - } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java index 5c89517..f9b2145 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/RdfUtils.java @@ -9,7 +9,6 @@ import java.io.StringWriter; public class RdfUtils { - public static Model fromTurtleString(String s) { try { return Rio.parse(new StringReader(s), RDFFormat.TURTLE); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java index 5d2261a..214beeb 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java @@ -7,7 +7,6 @@ import java.util.Map; public record ResourceInfo(String name, String uuid) { - public static Map createResourceInfoMap(List resourceResponseList){ Map fdpResourceMap = new HashMap<>(); for(ResourceResponse resourceResponse : resourceResponseList) { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java index f74c345..d700210 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java @@ -1,6 +1,6 @@ package nl.healthri.fdp.uploadschema.utils; -import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import java.util.HashMap; @@ -8,7 +8,6 @@ import java.util.Map; public record SchemaInfo(Version version, String uuid, String definition) { - public static Map createSchemaInfoMap(List schemaDataResponseList) { Map schemaInfoMap = new HashMap<>(); for (SchemaDataResponse schemaDataResponse : schemaDataResponseList) { diff --git a/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java similarity index 98% rename from src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java rename to src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java index eaa2197..0ad33e7 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/tasks/ShapeUpdateInsertTaskTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java @@ -1,7 +1,7 @@ -package nl.healthri.fdp.uploadschema.tasks; +package nl.healthri.fdp.uploadschema.services; import nl.healthri.fdp.uploadschema.integration.FdpClient; -import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; diff --git a/src/test/java/nl/healthri/fdp/uploadschema/utils/VersionTest.java b/src/test/java/nl/healthri/fdp/uploadschema/utils/VersionTest.java index 98fb4a8..29337e0 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/utils/VersionTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/utils/VersionTest.java @@ -1,6 +1,6 @@ package nl.healthri.fdp.uploadschema.utils; -import nl.healthri.fdp.uploadschema.Version; +import nl.healthri.fdp.uploadschema.domain.Version; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; From 4b3d0697a7abfb88e63b087d68ba3317c57c8617 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Tue, 4 Nov 2025 14:05:48 +0100 Subject: [PATCH 21/51] refactor: moved FdpService and added service annotations to each service --- .../fdp/uploadschema/SchemaTools.java | 4 ++-- .../FdpClient.java | 2 +- .../FdpClientInterface.java | 2 +- .../{integration => services}/FdpService.java | 5 +++-- .../services/FdpServiceInterface.java | 22 +++++++++++++++++++ .../services/ResourceTaskService.java | 3 ++- .../services/SchemaToolService.java | 3 ++- .../services/ShapeTaskService.java | 3 ++- .../services/ShapeUpdateInsertTaskTest.java | 2 +- 9 files changed, 36 insertions(+), 10 deletions(-) rename src/main/java/nl/healthri/fdp/uploadschema/{integration => integrations}/FdpClient.java (99%) rename src/main/java/nl/healthri/fdp/uploadschema/{integration => integrations}/FdpClientInterface.java (96%) rename src/main/java/nl/healthri/fdp/uploadschema/{integration => services}/FdpService.java (96%) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/services/FdpServiceInterface.java diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index f4497f5..d7c2613 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -1,8 +1,8 @@ package nl.healthri.fdp.uploadschema; import com.fasterxml.jackson.databind.ObjectMapper; -import nl.healthri.fdp.uploadschema.integration.FdpClient; -import nl.healthri.fdp.uploadschema.integration.FdpService; +import nl.healthri.fdp.uploadschema.integrations.FdpClient; +import nl.healthri.fdp.uploadschema.services.FdpService; import nl.healthri.fdp.uploadschema.services.ResourceTaskService; import nl.healthri.fdp.uploadschema.services.SchemaToolService; import nl.healthri.fdp.uploadschema.services.ShapeTaskService; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java similarity index 99% rename from src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java rename to src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java index df5feee..b69ae72 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.integration; +package nl.healthri.fdp.uploadschema.integrations; import com.fasterxml.jackson.databind.ObjectMapper; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClientInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java similarity index 96% rename from src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClientInterface.java rename to src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java index 0498825..6f45893 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpClientInterface.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.integration; +package nl.healthri.fdp.uploadschema.integrations; import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java similarity index 96% rename from src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java rename to src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java index a1bea26..9837db2 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integration/FdpService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.integration; +package nl.healthri.fdp.uploadschema.services; import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.domain.ResourceTask; @@ -9,6 +9,7 @@ import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; +import nl.healthri.fdp.uploadschema.integrations.FdpClientInterface; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import org.slf4j.Logger; @@ -20,7 +21,7 @@ @Service -public class FdpService { +public class FdpService implements FdpServiceInterface { private final FdpClientInterface fdpClient; private static final Logger logger = LoggerFactory.getLogger(FdpService.class); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/FdpServiceInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpServiceInterface.java new file mode 100644 index 0000000..ebb123e --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpServiceInterface.java @@ -0,0 +1,22 @@ +package nl.healthri.fdp.uploadschema.services; + +import nl.healthri.fdp.uploadschema.domain.ResourceTask; +import nl.healthri.fdp.uploadschema.domain.ShapeTask; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; + +import java.util.List; + +public interface FdpServiceInterface { + void authenticate(String username, String password); + + List getAllSchemas(); + + void createSchema(ShapeTask task); + void updateSchema(ShapeTask task); + void releaseSchema(ShapeTask task); + + List getAllResources(); + void createResource(ResourceTask task); + void updateResource(ResourceTask task); +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index b3fea25..a5919bf 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -3,12 +3,12 @@ import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.integration.FdpService; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.ResourceInfo; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; @@ -16,6 +16,7 @@ import static nl.healthri.fdp.uploadschema.utils.ResourceInfo.createResourceInfoMap; import static nl.healthri.fdp.uploadschema.utils.SchemaInfo.createSchemaInfoMap; +@Service public class ResourceTaskService implements ResourceTaskServiceInterface { public FdpService fdpService; public Properties properties; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java index 6ebb283..a977682 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java @@ -2,7 +2,6 @@ import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; -import nl.healthri.fdp.uploadschema.integration.FdpService; import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.RdfUtils; @@ -10,6 +9,7 @@ import org.eclipse.rdf4j.model.Model; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; import java.io.IOException; import java.nio.file.Files; @@ -19,6 +19,7 @@ import static java.util.function.Predicate.not; +@Service public class SchemaToolService implements SchemaToolServiceInterface { public FdpService fdpService; public ResourceTaskServiceInterface resourceTaskService; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java index b8264bf..a0f207e 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java @@ -4,13 +4,13 @@ import nl.healthri.fdp.uploadschema.domain.ShapeTask; import nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.integration.FdpService; import nl.healthri.fdp.uploadschema.utils.*; import nl.healthri.fdp.uploadschema.utils.Properties; import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.model.util.Models; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; import java.net.URI; import java.util.*; @@ -18,6 +18,7 @@ import static nl.healthri.fdp.uploadschema.utils.SchemaInfo.createSchemaInfoMap; +@Service public class ShapeTaskService implements ShapeTaskServiceInterface { public FdpService fdpService; public FileHandler fileHandler; diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java index 0ad33e7..fc2e646 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java @@ -1,6 +1,6 @@ package nl.healthri.fdp.uploadschema.services; -import nl.healthri.fdp.uploadschema.integration.FdpClient; +import nl.healthri.fdp.uploadschema.integrations.FdpClient; import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.utils.FileHandler; From 4e4564e177e9e96480e8d7016fc54896d0c1c268 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Tue, 4 Nov 2025 16:17:05 +0100 Subject: [PATCH 22/51] feature: initial commit for create task unit test --- .../services/ResourceTaskService.java | 6 +- .../fdp/uploadschema/utils/Properties.java | 4 + .../services/ResourceTaskServiceTest.java | 69 ++++++ .../services/ShapeTaskServiceTest.java | 4 + .../services/ShapeUpdateInsertTaskTest.java | 214 ------------------ 5 files changed, 80 insertions(+), 217 deletions(-) create mode 100644 src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java create mode 100644 src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java delete mode 100644 src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index a5919bf..72ee6fe 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -68,9 +68,9 @@ public List createParentTasks() { return this.properties.resources.entrySet().stream().map(entry -> { String parentResourceName = entry.getValue().parentResource(); String parentResourceUuid = ""; - String childName = ""; - String childIri = ""; - String childUuid = ""; + String childName = null; + String childIri = null; + String childUuid = null; boolean exists = false; ResourceInfo fdpResourceInfo = resourceInfoMap.get(parentResourceName); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java index 98b0327..af26ff4 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java @@ -183,5 +183,9 @@ public Set getParents(String child) { .filter(e -> e.getValue().contains(child)) .map(Map.Entry::getKey).collect(Collectors.toSet()); } + + public Map getResourceProperties() { + return this.resources; + } } diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java new file mode 100644 index 0000000..b4cc862 --- /dev/null +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -0,0 +1,69 @@ +package nl.healthri.fdp.uploadschema.services; + +import nl.healthri.fdp.uploadschema.domain.ResourceTask; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.utils.Properties; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.mockito.Mockito.when; + +public class ResourceTaskServiceTest { + + @Mock + FdpService fdpService; + @Mock + Properties properties; + + @InjectMocks + private ResourceTaskService resourceTaskService; + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + } + + @Test + void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse(){ + // given + String resourceName = "nonexistent-resource"; + Properties.ResourceProperties resourceProperty = new Properties.ResourceProperties("schema1", null, null); + when(properties.getResourceProperties()).thenReturn(Map.of(resourceName, resourceProperty)); + + // FDP returns no matching resources + when(fdpService.getAllResources()).thenReturn(List.of()); + + // FDP returns schemas + when(fdpService.getAllSchemas()).thenReturn(List.of( + new SchemaDataResponse("schema1", "schema-uuid-1", null, null, null, null, null) + )); + + // when + List result = resourceTaskService.createTasks(); + + // then + assertEquals(1, result.size()); + ResourceTask task = result.getFirst(); + assertEquals(resourceName, task.resource); + assertFalse(task.exists); + assertEquals("schema-uuid-1", task.shapeUUUID); + } + void ResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue(){ + + } + + void ParentResourceNotInSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo(){ + + } + void ParentResourceInSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithChildInfo(){ + + } +} diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java new file mode 100644 index 0000000..b057d35 --- /dev/null +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java @@ -0,0 +1,4 @@ +package nl.healthri.fdp.uploadschema.services; + +public class ShapeTaskServiceTest { +} diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java deleted file mode 100644 index fc2e646..0000000 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java +++ /dev/null @@ -1,214 +0,0 @@ -package nl.healthri.fdp.uploadschema.services; - -import nl.healthri.fdp.uploadschema.integrations.FdpClient; -import nl.healthri.fdp.uploadschema.domain.Version; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.utils.FileHandler; -import nl.healthri.fdp.uploadschema.utils.Properties; -import nl.healthri.fdp.uploadschema.utils.RdfUtils; -import nl.healthri.fdp.uploadschema.utils.SchemaInfo; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import java.net.URI; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class ShapeUpdateInsertTaskTest { - - /** - * Tests the functionality of the `ShapeUpdateInsertTask.createTasks` - * The test uses mocking to simulate: - *

- * - Fetching schema data from an FDP (Fair Data Point). - * - RDF model reading from files via a `FileHandler`. - *

- * The schema is present on FDP, but the schema of the file is different - * so the task will be labeled with "UPDATE" - */ - @Test - void testCreateTasks_updated_shape() { - // Mock Properties - Properties props = Mockito.mock(Properties.class); - props.schemasToPublish = List.of("TestShape"); - Mockito.when(props.getFiles()).thenReturn(Map.of("TestShape", List.of(URI.create("file:test.ttl")))); - Mockito.when(props.getVersion()).thenReturn(new Version("2.0.0")); - Mockito.when(props.getParents("TestShape")).thenReturn(Set.of("ParentShape")); - - // Mock FDP and its fetchSchemaFromFDP result - SchemaInfo shapesOnFdp = createFdpShapeMap( - createFdpResponse("TestShape", "", "1.0.0", "uuid")); - - FdpClient fdpClient = Mockito.mock(FdpClient.class); - Mockito.when(fdpClient.fetchSchemas()).thenReturn(shapesOnFdp); - - // Mock FileHandler - FileHandler fileHandler = Mockito.mock(FileHandler.class); - Mockito.when(fileHandler.readFiles(Mockito.anyList())).thenReturn(RdfUtils.fromTurtleString(getShapeModel2())); - - // Run createTasks - List tasks = ShapeUpdateInsertTask.createTasks(props, fdpClient, fileHandler); - - // Assert - assertEquals(1, tasks.size()); - ShapeUpdateInsertTask task = tasks.getFirst(); - assertEquals("TestShape", task.shape); - assertEquals(new Version("2.0.0"), task.version); - assertEquals(getShapeModel2(), task.model); - assertEquals(ShapeUpdateInsertTask.ShapeStatus.UPDATE, task.status); - } - - /** - * Tests the functionality of the `ShapeUpdateInsertTask.createTasks` - * The test uses mocking to simulate: - *

- * - Fetching schema data from an FDP (Fair Data Point). - * - RDF model reading from files via a `FileHandler`. - *

- * The schema is on FDP and is the same as from the file. So it the task will be labeled with "SAME" - */ - @Test - void testCreateTasks_identical_shape() { - // Mock Properties - Properties props = Mockito.mock(Properties.class); - props.schemasToPublish = List.of("TestShape"); - Mockito.when(props.getFiles()).thenReturn(Map.of("TestShape", List.of(URI.create("file:test.ttl")))); - Mockito.when(props.getVersion()).thenReturn(new Version("2.0.0")); - Mockito.when(props.getParents("TestShape")).thenReturn(Set.of("ParentShape")); - - // Mock FDP and its fetchSchemaFromFDP result - SchemaInfo shapesOnFdp = createFdpShapeMap( - createFdpResponse("TestShape", getShapeModel1(), "1.0.0", "uuid")); - - FdpClient fdpClient = Mockito.mock(FdpClient.class); - Mockito.when(fdpClient.fetchSchemas()).thenReturn(shapesOnFdp); - - // Mock FileHandler - FileHandler fileHandler = Mockito.mock(FileHandler.class); - Mockito.when(fileHandler.readFiles(Mockito.anyList())).thenReturn(RdfUtils.fromTurtleString(getShapeModel1())); - - // Run createTasks - List tasks = ShapeUpdateInsertTask.createTasks(props, fdpClient, fileHandler); - - // Assert - assertEquals(1, tasks.size()); - ShapeUpdateInsertTask task = tasks.getFirst(); - assertEquals("TestShape", task.shape); - assertEquals(new Version("2.0.0"), task.version); - assertEquals(getShapeModel1(), task.model); - assertEquals(ShapeUpdateInsertTask.ShapeStatus.SAME, task.status); - } - - /** - * Tests the functionality of the `ShapeUpdateInsertTask.createTasks` - * The test uses mocking to simulate: - *

- * - Fetching schema data from an FDP (Fair Data Point). - * - RDF model reading from files via a `FileHandler`. - *

- * The schema is not present on the FDP, so the task will be labeled with "SAME" - */ - @Test - void testCreateTasks_new() { - // Mock Properties - Properties props = Mockito.mock(Properties.class); - props.schemasToPublish = List.of("TestShape"); - Mockito.when(props.getFiles()).thenReturn(Map.of("TestShape", List.of(URI.create("file:test.ttl")))); - Mockito.when(props.getVersion()).thenReturn(new Version("2.0.0")); - Mockito.when(props.getParents("TestShape")).thenReturn(Set.of("ParentShape")); - - // Mock FDP and its fetchSchemaFromFDP result - SchemaInfo shapesOnFdp = createFdpShapeMap( - createFdpResponse("JustAnotherShape", "", "1.0.0", "uuid")); - - FdpClient fdpClient = Mockito.mock(FdpClient.class); - Mockito.when(fdpClient.fetchSchemas()).thenReturn(shapesOnFdp); - - // Mock FileHandler - FileHandler fileHandler = Mockito.mock(FileHandler.class); - Mockito.when(fileHandler.readFiles(Mockito.anyList())).thenReturn(RdfUtils.fromTurtleString(getShapeModel2())); - - // Run createTasks - List tasks = ShapeUpdateInsertTask.createTasks(props, fdpClient, fileHandler); - - // Assert - assertEquals(1, tasks.size()); - ShapeUpdateInsertTask task = tasks.getFirst(); - assertEquals("TestShape", task.shape); - assertEquals(new Version("2.0.0"), task.version); - assertEquals(getShapeModel2(), task.model); - assertEquals(ShapeUpdateInsertTask.ShapeStatus.INSERT, task.status); - } - - private SchemaInfo createFdpShapeMap(SchemaDataResponse... responses) { - return new SchemaInfo(responses); - } - - private SchemaDataResponse createFdpResponse(String name, String definition, String version, String uuid) { - SchemaDataResponse.Latest latest = new SchemaDataResponse.Latest(uuid, - version, uuid, - "", - name, true, false, true, - "", "", "", definition, "", null, null, "", ""); - - return new SchemaDataResponse(uuid, name, latest, null, null, null, null); - } - - private String getShapeModel1() { - return linter(""" - @prefix ex: . - @prefix sh: . - @prefix xsd: . - @prefix foaf: . - - ex:PersonShape a sh:NodeShape ; - sh:targetClass foaf:Person ; - sh:property ex:NamePropertyShape ; - sh:property ex:AgePropertyShape . - - ex:NamePropertyShape a sh:PropertyShape ; - sh:path foaf:name ; - sh:datatype xsd:string ; - sh:minCount 1 . - - ex:AgePropertyShape a sh:PropertyShape ; - sh:path foaf:age ; - sh:datatype xsd:integer ; - sh:minInclusive 0 ; - sh:maxCount 1 ."""); - } - - private String linter(String s) { - //make sure the model is properly formatted - return RdfUtils.modelAsTurtleString(RdfUtils.fromTurtleString(s)); - } - - private String getShapeModel2() { - - return linter(""" - @prefix ex: . - @prefix sh: . - @prefix xsd: . - @prefix foaf: . - - ex:PersonShape a sh:NodeShape ; - sh:targetClass foaf:Person ; - sh:property ex:NamePropertyShape ; - sh:property ex:AgePropertyShape . - - ex:NamePropertyShape a sh:PropertyShape ; - sh:path foaf:name ; - sh:datatype xsd:string ; - sh:minCount 100 . - - ex:AgePropertyShape a sh:PropertyShape ; - sh:path foaf:age ; - sh:datatype xsd:integer ; - sh:minInclusive 0 ; - sh:maxCount 1 ."""); - } -} - From 06624c3c2ee581320aa99f10e23633181edaec90 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Wed, 5 Nov 2025 12:01:22 +0100 Subject: [PATCH 23/51] tests: added dummy data from fdp schemas and resources and all edge cases for ResourceTaskService --- .../services/ResourceTaskServiceTest.java | 410 ++++++++++++++++-- 1 file changed, 379 insertions(+), 31 deletions(-) diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index b4cc862..408c648 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -1,69 +1,417 @@ package nl.healthri.fdp.uploadschema.services; import nl.healthri.fdp.uploadschema.domain.ResourceTask; +import nl.healthri.fdp.uploadschema.domain.Version; +import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.utils.Properties; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.ArrayList; import java.util.List; -import java.util.Map; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.mockito.Mockito.when; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; -public class ResourceTaskServiceTest { +class ResourceTaskServiceTest { - @Mock - FdpService fdpService; - @Mock - Properties properties; - - @InjectMocks + private FdpService fdpServiceMock; + private Properties properties; private ResourceTaskService resourceTaskService; @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); + fdpServiceMock = mock(FdpService.class); + getProperties(); + resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); + } + + private void getProperties() { + Properties props = new Properties(); + + props.schemas.put("Resource", List.of("Resource.ttl")); + props.schemas.put("Distribution", List.of("Distribution.ttl", "PeriodOfTime.ttl", "Checksum.ttl")); + props.schemas.put("Dataset", List.of("Dataset.ttl", "Agent.ttl", "Kind.ttl")); + + props.parentChild.put("Resource", List.of("Dataset", "Catalog", "Data Service")); + + props.resources.put("Sample Distribution", + new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/adms#sample", "Distribution")); + props.resources.put("Dataset Series", + new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/dcat#inSeries", "Dataset Series")); + props.resources.put("Analytics Distribution", + new Properties.ResourceProperties("Dataset", "http://healthdataportal.eu/ns/health#analytics", "Distribution")); + + props.schemasToPublish = List.of("Resource", "Catalog", "Dataset", "Dataset Series", "Distribution", "Data Service"); + props.schemaVersion = "2.0.0"; + + this.properties = props; } @Test - void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse(){ + void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() { // given - String resourceName = "nonexistent-resource"; - Properties.ResourceProperties resourceProperty = new Properties.ResourceProperties("schema1", null, null); - when(properties.getResourceProperties()).thenReturn(Map.of(resourceName, resourceProperty)); + List resourceResponseList = List.of( + new ResourceResponse( + "2f08228e-1789-40f8-84cd-28e3288c3604", + "Dataset", + null, + null, + null, + null, + null + ), + new ResourceResponse( + "02c649de-c579-43bb-b470-306abdc808c7", + "Distribution", + null, + null, + null, + null, + null + ), + new ResourceResponse( + "77aaad6a-0136-4c6e-88b9-07ffccd0ee4c", + "FAIR Data Point", + null, + null, + null, + null, + null + ), + new ResourceResponse( + "fc089ccc-c06d-4090-bf46-74b9192e5d04", + "Dataset Series", + null, + null, + null, + null, + null + ), + new ResourceResponse( + "2da98613-5673-4741-b131-a1410953c3f0", + "Analytics Distribution", + null, + null, + null, + null, + null + ), + new ResourceResponse( + "b117e67a-937c-4115-be6d-d79ef5ddadf4", + "Sample Distribution", + null, + null, + null, + null, + null + ) + ); - // FDP returns no matching resources - when(fdpService.getAllResources()).thenReturn(List.of()); + List schemaDataResponseList = List.of( + new SchemaDataResponse( + "6f7a5a76-6185-4bd0-9fe9-62ecc90c9bad", + "Metadata Service", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "a92958ab-a414-47e6-8e17-68ba96ba3a2b", + "FAIR Data Point", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "6a668323-3936-4b53-8380-a4fd2ed082ee", + "Resource", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "866d7fb8-5982-4215-9c7c-18d0ed1bd5f3", + "Dataset", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "0bc517a8-79e5-427a-b0a5-100aa32d58ee", + "Dataset Series", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "ebacbf83-cd4f-4113-8738-d73c0735b0ab", + "Distribution", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "89d94c1b-f6ff-4545-ba9b-120b2d1921d0", + "Data Service", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "2aa7ba63-d27a-4c0e-bfa6-3a4e250f4660", + "Catalog", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "ebacbf83-cd4f-4113-8738-d73c0735b0ab", + "Distribution", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "ebacbf83-cd4f-4113-8738-d73c0735b0ab", + "Distribution", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + null, + null, + null + ) + ); - // FDP returns schemas - when(fdpService.getAllSchemas()).thenReturn(List.of( - new SchemaDataResponse("schema1", "schema-uuid-1", null, null, null, null, null) - )); + when(fdpServiceMock.getAllResources()).thenReturn(resourceResponseList); + + when(fdpServiceMock.getAllSchemas()).thenReturn(schemaDataResponseList); // when List result = resourceTaskService.createTasks(); // then - assertEquals(1, result.size()); - ResourceTask task = result.getFirst(); - assertEquals(resourceName, task.resource); - assertFalse(task.exists); - assertEquals("schema-uuid-1", task.shapeUUUID); + assertEquals(3, result.size()); // 3 resources defined in properties + ResourceTask sampleDist = result.stream() + .filter(r -> r.resource.equals("Sample Distribution")) + .findFirst() + .orElseThrow(); } - void ResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue(){ + + @Test + void ResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { } - void ParentResourceNotInSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo(){ + @Test + void ParentResourceNotInSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo() { + } + + @Test void ParentResourceInSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithChildInfo(){ } -} +} \ No newline at end of file From 5eee6d89872df2ca6e7e7d4d8aea3fdd21eef203 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Mon, 10 Nov 2025 10:07:34 +0100 Subject: [PATCH 24/51] tests: added all test scenarios for ResourceTaskService --- .../services/ResourceTaskService.java | 7 +- .../services/ResourceTaskServiceTest.java | 428 +++++++++++++++++- 2 files changed, 413 insertions(+), 22 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index 72ee6fe..d3ddf0b 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -40,6 +40,7 @@ public List createTasks() { return properties.resources.entrySet().stream().map(entry -> { String resourceName = entry.getKey(); String resourceUuid = ""; + String schemaUUID = ""; boolean exists = false; ResourceInfo fdpResourceInfo = resourceInfoMap.get(resourceName); @@ -50,7 +51,11 @@ public List createTasks() { String schema = entry.getValue().schema(); String name = schema.isBlank() ? resourceName : schema; - String schemaUUID = schemaInfoMap.get(name).uuid(); + + SchemaInfo schemaInfo = schemaInfoMap.get(name); + if(schemaInfo != null){ + schemaUUID = schemaInfoMap.get(name).uuid(); + } return new ResourceTask( resourceName, diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index 408c648..310de24 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -5,18 +5,23 @@ import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.utils.Properties; +import nl.healthri.fdp.uploadschema.utils.ResourceInfo; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import static nl.healthri.fdp.uploadschema.utils.ResourceInfo.createResourceInfoMap; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; class ResourceTaskServiceTest { + @Mock private FdpService fdpServiceMock; private Properties properties; private ResourceTaskService resourceTaskService; @@ -24,7 +29,6 @@ class ResourceTaskServiceTest { @BeforeEach void setUp() { MockitoAnnotations.openMocks(this); - fdpServiceMock = mock(FdpService.class); getProperties(); resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); } @@ -51,8 +55,407 @@ private void getProperties() { this.properties = props; } + @Test void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() { + // given + List resourceResponseList = List.of( + new ResourceResponse( + "1", + "Resource", + null, null, null, null, null + ), + new ResourceResponse( + "2", + "Distribution", + null, null, null, null, null + + ), + new ResourceResponse( + "3", + "Dataset", + null, null, null, null, null + + ) + ); + + List schemaDataResponseList = List.of( + new SchemaDataResponse( + "1", + "test", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "2", + "test2", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "3", + "test3", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ) + ); + + when(fdpServiceMock.getAllResources()).thenReturn(resourceResponseList); + + when(fdpServiceMock.getAllSchemas()).thenReturn(schemaDataResponseList); + + // when + List result = resourceTaskService.createTasks(); + + // then + assertEquals(3, result.size()); + for(ResourceTask task : result){ + assertEquals(false, task.exists); + } + } + + @Test + void ResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { + // given + List resourceResponseList = List.of( + new ResourceResponse( + "1", + "Resource", + null, null, null, null, null + ), + new ResourceResponse( + "2", + "Distribution", + null, null, null, null, null + + ), + new ResourceResponse( + "3", + "Dataset", + null, null, null, null, null + + ) + ); + + List schemaDataResponseList = List.of( + new SchemaDataResponse( + "1", + "Resource", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "2", + "Distribution", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "3", + "Dataset", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ) + ); + + when(fdpServiceMock.getAllResources()).thenReturn(resourceResponseList); + + when(fdpServiceMock.getAllSchemas()).thenReturn(schemaDataResponseList); + + // when + List result = resourceTaskService.createTasks(); + + // then + assertEquals(3, result.size()); + for(ResourceTask task : result){ + assertEquals(false, task.exists); + } + } + + @Test + void ParentResourceNotInSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo() { + // given + List resourceResponseList = List.of( + new ResourceResponse( + "1", + "Resource", + null, null, null, null, null + ), + new ResourceResponse( + "2", + "Distribution", + null, null, null, null, null + + ), + new ResourceResponse( + "3", + "Dataset", + null, null, null, null, null + + ) + ); + + when(fdpServiceMock.getAllResources()).thenReturn(resourceResponseList); + + // when + List result = resourceTaskService.createParentTasks(); + + // then + assertEquals(3, result.size()); + for(ResourceTask task : result){ + assertEquals(false, task.exists); + } + } + + @Test + void ParentResourceInSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithChildInfo(){ + // given + List resourceResponseList = List.of( + new ResourceResponse( + "1", + "Resource", + null, null, null, null, null + ), + new ResourceResponse( + "2", + "Distribution", + null, null, null, null, null + + ), + new ResourceResponse( + "3", + "Dataset", + null, null, null, null, null + + ) + ); + + List schemaDataResponseList = List.of( + new SchemaDataResponse( + "1", + "Resource", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "2", + "Distribution", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ), + new SchemaDataResponse( + "3", + "Dataset", + new SchemaDataResponse.Latest( + null, + new Version(1, 0, 0).toString(), + null, + null, + null, + false, + false, + true, + null, + null, + null, + null, + null, + null, + null, + null, + null + ), + null, + new ArrayList<>(List.of(new Version(1, 0, 0).toString())), + null, + null + ) + ); + + when(fdpServiceMock.getAllResources()).thenReturn(resourceResponseList); + + when(fdpServiceMock.getAllSchemas()).thenReturn(schemaDataResponseList); + + // when + List result = resourceTaskService.createTasks(); + + // then + assertEquals(3, result.size()); + for(ResourceTask task : result){ + assertEquals(false, task.exists); + } + } + + @Test + void TestResourceTaskService_RealScenario() { // given List resourceResponseList = List.of( new ResourceResponse( @@ -393,25 +796,8 @@ void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() // then assertEquals(3, result.size()); // 3 resources defined in properties - ResourceTask sampleDist = result.stream() - .filter(r -> r.resource.equals("Sample Distribution")) - .findFirst() - .orElseThrow(); - } - - @Test - void ResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { - - } - - @Test - void ParentResourceNotInSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo() { - - - } - - @Test - void ParentResourceInSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithChildInfo(){ - + for(ResourceTask task : result){ + assertEquals(true, task.exists); + } } } \ No newline at end of file From d9eebf6bedec5125566ac51aed636ac00d0462c6 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Mon, 10 Nov 2025 14:07:05 +0100 Subject: [PATCH 25/51] tests: Added all tests for ShapeTaskService --- .../services/ShapeTaskService.java | 14 +- .../fdp/uploadschema/utils/Properties.java | 5 + .../services/ShapeTaskServiceTest.java | 276 +++++++++++++++++- 3 files changed, 287 insertions(+), 8 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java index a0f207e..49afb75 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java @@ -20,14 +20,14 @@ @Service public class ShapeTaskService implements ShapeTaskServiceInterface { - public FdpService fdpService; + public FdpServiceInterface fdpService; public FileHandler fileHandler; public Properties properties; private static final Logger logger = LoggerFactory.getLogger(ShapeTaskService.class); - public ShapeTaskService(FdpService fdpService, FileHandler fileHandler, Properties properties) { - this.fdpService = fdpService; + public ShapeTaskService(FdpServiceInterface fdpServiceInterface, FileHandler fileHandler, Properties properties) { + this.fdpService = fdpServiceInterface; this.fileHandler = fileHandler; this.properties = properties; } @@ -35,18 +35,18 @@ public ShapeTaskService(FdpService fdpService, FileHandler fileHandler, Properti public List createTasks() { Map> files = this.properties.getFiles(); List schemaDataResponseList = this.fdpService.getAllSchemas(); - Map schemaInfoMap = createSchemaInfoMap(schemaDataResponseList); + Map shapesOnFdp = createSchemaInfoMap(schemaDataResponseList); //list of the task we have to do for insert/updating shacls - return this.properties.schemasToPublish.stream().map(schemaTitle -> { + return this.properties.getSchemasToPublish().stream().map(schemaTitle -> { List ttlFiles = Optional.ofNullable(files.get(schemaTitle)).orElseThrow(() -> new NoSuchElementException(schemaTitle + " not present in schema section of yaml-file")); Model newModel = fileHandler.readFiles(ttlFiles); String model = RdfUtils.modelAsTurtleString(newModel); Version requestedVersion = this.properties.getVersion(); Set parents = this.properties.getParents(schemaTitle); - if (schemaInfoMap.containsKey(schemaTitle)) { - SchemaInfo matchingFdpSchema = schemaInfoMap.get(schemaTitle); + if (shapesOnFdp.containsKey(schemaTitle)) { + SchemaInfo matchingFdpSchema = shapesOnFdp.get(schemaTitle); Version version = matchingFdpSchema.version().next(requestedVersion); String uuid = matchingFdpSchema.uuid(); Model fdpSchemaModel = RdfUtils.fromTurtleString(matchingFdpSchema.definition()); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java index af26ff4..c8f119a 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java @@ -111,6 +111,11 @@ public Version getVersion() { return new Version(schemaVersion); } + @JsonIgnore + public List getSchemasToPublish() { + return this.schemasToPublish; + } + @JsonIgnore public Path getPiecesDir() { return Path.of(outputRoot, piecesDir); diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java index b057d35..88ad0d4 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java @@ -1,4 +1,278 @@ package nl.healthri.fdp.uploadschema.services; -public class ShapeTaskServiceTest { +import nl.healthri.fdp.uploadschema.domain.Version; +import nl.healthri.fdp.uploadschema.domain.ShapeTask; +import nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus; +import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.utils.*; +import nl.healthri.fdp.uploadschema.utils.Properties; +import org.eclipse.rdf4j.model.Model; +import org.eclipse.rdf4j.model.impl.LinkedHashModel; +import org.eclipse.rdf4j.model.util.Models; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; + +import java.net.URI; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class ShapeTaskServiceTest { + + @Mock + private FdpServiceInterface fdpServiceMock; + @Mock + private FileHandler fileHandlerMock; + @Mock + private Properties propertiesMock; + private ShapeTaskService shapeTaskService; + + @BeforeEach + void setUp() { + fdpServiceMock = mock(FdpService.class); + fileHandlerMock = mock(FileHandler.class); + propertiesMock = mock(Properties.class); + shapeTaskService = new ShapeTaskService(fdpServiceMock, fileHandlerMock, propertiesMock); + } + + Model newModel() { + String ttl = """ + @prefix ex: . + @prefix foaf: . + + ex:Alice a foaf:Person ; + foaf:name "Alice" ; + foaf:age 30 . + """; + + return RdfUtils.fromTurtleString(ttl); + } + + Model newDifferentModel() { + String ttl = """ + @prefix ex: . + @prefix foaf: . + + ex:Alice a foaf:Person ; + foaf:name "Peter" ; + foaf:age 40 . + """; + + return RdfUtils.fromTurtleString(ttl); + } + + @Test + void propertiesSchemaTitleFoundInPropertiesFiles_WhenLookingForTitleKeyValue_ReturnsNewShapeTask() { + // Arrange + String schemaTitle = "TestSchema"; + URI fileUri = URI.create("file://test-schema.ttl"); + List uris = List.of(fileUri); + Version version = new Version("1.0.0"); + + when(propertiesMock.getFiles()).thenReturn(Map.of(schemaTitle, uris)); + when(propertiesMock.getSchemasToPublish()).thenReturn(List.of(schemaTitle)); + when(propertiesMock.getVersion()).thenReturn(version); + when(propertiesMock.getParents(schemaTitle)).thenReturn(Set.of()); + when(fdpServiceMock.getAllSchemas()).thenReturn(Collections.emptyList()); + + Model model = new LinkedHashModel(); + when(fileHandlerMock.readFiles(uris)).thenReturn(model); + + // Act + List tasks = shapeTaskService.createTasks(); + + // Assert + assertEquals(1, tasks.size()); + ShapeTask task = tasks.getFirst(); + assertEquals(schemaTitle, task.shape); + assertEquals(ShapeStatus.INSERT, task.status()); + assertEquals(version, task.version); + } + + @Test + void propertiesSchemaTitleNotFoundInPropertiesFiles_WhenLookingForTitleKeyValue_ReturnsNoSuchElementException() { + // Arrange + String schemaTitle = "MissingSchema"; + + // Act + when(propertiesMock.getSchemasToPublish()).thenReturn(List.of(schemaTitle)); + when(propertiesMock.getFiles()).thenReturn(Map.of()); + + // Assert + assertThrows(NoSuchElementException.class, () -> shapeTaskService.createTasks()); + } + + @Test + void propertiesSchemaTitleFoundInFdpSchemaInfoMap_WhenLookingForTitleKeyValue_ReturnsShapeTaskWithStatusInsert() { + // Arrange + String schemaTitle = "InsertSchema"; + URI uri = URI.create("file://insert-schema.ttl"); + Version version = new Version("1.0.0"); + + Model model = newModel(); + String ttl = RdfUtils.modelAsTurtleString(model); + + SchemaDataResponse.Latest latest = new SchemaDataResponse.Latest( + "uuid-latest", "1.0.0", "vUuid", null, schemaTitle, + true, false, true, "type", "origin", "imported", ttl, "desc", + new ArrayList<>(), new ArrayList<>(), "res", "prefix" + ); + + SchemaDataResponse fdpSchemaDataResponse = new SchemaDataResponse( + "uuid-main", schemaTitle, latest, null, + new ArrayList<>(), new ArrayList<>(), new ArrayList<>() + ); + + when(propertiesMock.getFiles()).thenReturn(Map.of(schemaTitle, List.of(uri))); + when(propertiesMock.getSchemasToPublish()).thenReturn(List.of(schemaTitle)); + when(propertiesMock.getVersion()).thenReturn(version); + when(propertiesMock.getParents(schemaTitle)).thenReturn(Set.of()); + when(fdpServiceMock.getAllSchemas()).thenReturn(List.of(fdpSchemaDataResponse)); + when(fileHandlerMock.readFiles(List.of(uri))).thenReturn(model); + + // Act + List tasks = shapeTaskService.createTasks(); + + // Assert + assertEquals(1, tasks.size()); + assertEquals(ShapeStatus.SAME, tasks.getFirst().status()); + } + + @Test + void propertiesSchemaTitleNotFoundInFdpSchemaInfoMap_WhenLookingForTitleKeyValue_ReturnsShapeTaskWithStatusSameOrUpdate() { + // Arrange + String schemaTitle = "InsertSchema"; + URI uri = URI.create("file://insert-schema.ttl"); + Version version = new Version("1.0.0"); + + when(propertiesMock.getFiles()).thenReturn(Map.of(schemaTitle, List.of(uri))); + when(propertiesMock.getSchemasToPublish()).thenReturn(List.of(schemaTitle)); + when(propertiesMock.getVersion()).thenReturn(version); + when(propertiesMock.getParents(schemaTitle)).thenReturn(Set.of()); + when(fdpServiceMock.getAllSchemas()).thenReturn(Collections.emptyList()); + + Model model = newModel(); + when(fileHandlerMock.readFiles(List.of(uri))).thenReturn(model); + + // Act + List tasks = shapeTaskService.createTasks(); + + // Assert + assertEquals(1, tasks.size()); + assertEquals(ShapeStatus.INSERT, tasks.getFirst().status()); + } + + @Test + void NoChangesFound_WhenComparingPropertiesFileWithMatchingFdpShapeFile_ReturnsNewShapeTaskWithStatusSame() { + // Arrange + String schemaTitle = "SameSchema"; + URI fileUri = URI.create("file://same-schema.ttl"); + List uris = List.of(fileUri); + Version version = new Version("1.0.0"); + + Model model = newModel(); + Model sameModel = newModel(); + String ttlDifferentModel = RdfUtils.modelAsTurtleString(sameModel); + + SchemaDataResponse.Latest latest = new SchemaDataResponse.Latest( + "uuid-latest", + "1.0.0", + "versionUuid", + null, + schemaTitle, + true, + false, + true, + "type", + "origin", + "importedFrom", + ttlDifferentModel, + "desc", + new ArrayList<>(), + new ArrayList<>(), + "resName", + "urlPrefix" + ); + + SchemaDataResponse existingResponse = new SchemaDataResponse( + "uuid-main", + schemaTitle, + latest, + null, + new ArrayList<>(), + new ArrayList<>(), + new ArrayList<>() + ); + + when(propertiesMock.getFiles()).thenReturn(Map.of(schemaTitle, uris)); + when(propertiesMock.getSchemasToPublish()).thenReturn(List.of(schemaTitle)); + when(propertiesMock.getVersion()).thenReturn(version); + when(propertiesMock.getParents(schemaTitle)).thenReturn(Set.of()); + when(fdpServiceMock.getAllSchemas()).thenReturn(List.of(existingResponse)); + when(fileHandlerMock.readFiles(uris)).thenReturn(model); + + // Act + List tasks = shapeTaskService.createTasks(); + + // Assert + assertEquals(ShapeStatus.SAME, tasks.getFirst().status()); + } + + @Test + void ChangesFound_WhenComparingPropertiesFileWithMatchingFdpShapeFile_ReturnsNewShapeTaskWithStatusUpdate() { + // Arrange + String schemaTitle = "SameSchema"; + URI fileUri = URI.create("file://same-schema.ttl"); + List uris = List.of(fileUri); + Version version = new Version("1.0.0"); + + Model model = newModel(); + Model sameModel = newDifferentModel(); + String ttlDifferentModel = RdfUtils.modelAsTurtleString(sameModel); + + SchemaDataResponse.Latest latest = new SchemaDataResponse.Latest( + "uuid-latest", + "1.0.0", + "versionUuid", + null, + schemaTitle, + true, + false, + true, + "type", + "origin", + "importedFrom", + ttlDifferentModel, + "desc", + new ArrayList<>(), + new ArrayList<>(), + "resName", + "urlPrefix" + ); + + SchemaDataResponse existingResponse = new SchemaDataResponse( + "uuid-main", + schemaTitle, + latest, + null, + new ArrayList<>(), + new ArrayList<>(), + new ArrayList<>() + ); + + when(propertiesMock.getFiles()).thenReturn(Map.of(schemaTitle, uris)); + when(propertiesMock.getSchemasToPublish()).thenReturn(List.of(schemaTitle)); + when(propertiesMock.getVersion()).thenReturn(version); + when(propertiesMock.getParents(schemaTitle)).thenReturn(Set.of()); + when(fdpServiceMock.getAllSchemas()).thenReturn(List.of(existingResponse)); + when(fileHandlerMock.readFiles(uris)).thenReturn(model); + + // Act + List tasks = shapeTaskService.createTasks(); + + // Assert + assertEquals(ShapeStatus.UPDATE, tasks.getFirst().status()); + } } From 45e454005d2dca2ef9055f226c8fc188f750db1e Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Mon, 10 Nov 2025 14:31:54 +0100 Subject: [PATCH 26/51] fix: null on properties.schemasToPushblish because of @JsonIgnore --- Properties.yaml | 2 +- .../fdp/uploadschema/services/ResourceTaskService.java | 4 ++-- .../healthri/fdp/uploadschema/services/SchemaToolService.java | 4 ++-- .../java/nl/healthri/fdp/uploadschema/utils/Properties.java | 1 - 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Properties.yaml b/Properties.yaml index 6f0801e..40d0664 100644 --- a/Properties.yaml +++ b/Properties.yaml @@ -67,4 +67,4 @@ outputRoot: "C:\\Users\\PatrickDekker(Health\\IdeaProjects\\health-ri-metadata\\ Core\\" piecesDir: "PiecesShape" fairDataPointDir: "FairDataPointShape" -validationDir: "ValidationShape" +validationDir: "ValidationShape" \ No newline at end of file diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index d3ddf0b..79bc9ed 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -18,12 +18,12 @@ @Service public class ResourceTaskService implements ResourceTaskServiceInterface { - public FdpService fdpService; + public FdpServiceInterface fdpService; public Properties properties; private static final Logger logger = LoggerFactory.getLogger(ResourceTaskService.class); - public ResourceTaskService(FdpService fdpService, Properties properties) { + public ResourceTaskService(FdpServiceInterface fdpService, Properties properties) { this.fdpService = fdpService; this.properties = properties; } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java index a977682..6e39257 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java @@ -21,7 +21,7 @@ @Service public class SchemaToolService implements SchemaToolServiceInterface { - public FdpService fdpService; + public FdpServiceInterface fdpService; public ResourceTaskServiceInterface resourceTaskService; public ShapeTaskServiceInterface shapeTaskService; public Properties properties; @@ -29,7 +29,7 @@ public class SchemaToolService implements SchemaToolServiceInterface { private static final Logger logger = LoggerFactory.getLogger(SchemaToolService.class); - public SchemaToolService(FdpService fdpService, ResourceTaskServiceInterface resourceTaskService, ShapeTaskServiceInterface shapeTaskService, Properties properties, FileHandler fileHandler) { + public SchemaToolService(FdpServiceInterface fdpService, ResourceTaskServiceInterface resourceTaskService, ShapeTaskServiceInterface shapeTaskService, Properties properties, FileHandler fileHandler) { this.fdpService = fdpService; this.resourceTaskService = resourceTaskService; this.shapeTaskService = shapeTaskService; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java index c8f119a..cb0bed0 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java @@ -111,7 +111,6 @@ public Version getVersion() { return new Version(schemaVersion); } - @JsonIgnore public List getSchemasToPublish() { return this.schemasToPublish; } From 4ea01329a70d332873fceb40703ae934c23ae52d Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Mon, 10 Nov 2025 14:49:57 +0100 Subject: [PATCH 27/51] refactor: improved reusability for ResourceTaskServiceTest.java --- .../services/ResourceTaskServiceTest.java | 330 +++--------------- 1 file changed, 56 insertions(+), 274 deletions(-) diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index 310de24..61a31dd 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -5,7 +5,6 @@ import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.utils.Properties; -import nl.healthri.fdp.uploadschema.utils.ResourceInfo; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; @@ -13,9 +12,7 @@ import java.util.ArrayList; import java.util.List; -import java.util.Map; -import static nl.healthri.fdp.uploadschema.utils.ResourceInfo.createResourceInfoMap; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @@ -34,32 +31,29 @@ void setUp() { } private void getProperties() { - Properties props = new Properties(); + Properties properties = new Properties(); - props.schemas.put("Resource", List.of("Resource.ttl")); - props.schemas.put("Distribution", List.of("Distribution.ttl", "PeriodOfTime.ttl", "Checksum.ttl")); - props.schemas.put("Dataset", List.of("Dataset.ttl", "Agent.ttl", "Kind.ttl")); + properties.schemas.put("Resource", List.of("Resource.ttl")); + properties.schemas.put("Distribution", List.of("Distribution.ttl", "PeriodOfTime.ttl", "Checksum.ttl")); + properties.schemas.put("Dataset", List.of("Dataset.ttl", "Agent.ttl", "Kind.ttl")); - props.parentChild.put("Resource", List.of("Dataset", "Catalog", "Data Service")); + properties.parentChild.put("Resource", List.of("Dataset", "Catalog", "Data Service")); - props.resources.put("Sample Distribution", + properties.resources.put("Sample Distribution", new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/adms#sample", "Distribution")); - props.resources.put("Dataset Series", + properties.resources.put("Dataset Series", new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/dcat#inSeries", "Dataset Series")); - props.resources.put("Analytics Distribution", + properties.resources.put("Analytics Distribution", new Properties.ResourceProperties("Dataset", "http://healthdataportal.eu/ns/health#analytics", "Distribution")); - props.schemasToPublish = List.of("Resource", "Catalog", "Dataset", "Dataset Series", "Distribution", "Data Service"); - props.schemaVersion = "2.0.0"; + properties.schemasToPublish = List.of("Resource", "Catalog", "Dataset", "Dataset Series", "Distribution", "Data Service"); + properties.schemaVersion = "2.0.0"; - this.properties = props; + this.properties = properties; } - - @Test - void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() { - // given - List resourceResponseList = List.of( + List getResourceResponseList() { + return List.of( new ResourceResponse( "1", "Resource", @@ -78,11 +72,13 @@ void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() ) ); + } - List schemaDataResponseList = List.of( + List getSchemaDataResponseList(String name1, String name2, String name3) { + return List.of( new SchemaDataResponse( "1", - "test", + name1, new SchemaDataResponse.Latest( null, new Version(1, 0, 0).toString(), @@ -109,7 +105,7 @@ void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() ), new SchemaDataResponse( "2", - "test2", + name2, new SchemaDataResponse.Latest( null, new Version(1, 0, 0).toString(), @@ -136,7 +132,7 @@ void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() ), new SchemaDataResponse( "3", - "test3", + name3, new SchemaDataResponse.Latest( null, new Version(1, 0, 0).toString(), @@ -162,130 +158,36 @@ void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() null ) ); + } + + @Test + void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() { + // Arrange + List fdpResourceResponseList = getResourceResponseList(); - when(fdpServiceMock.getAllResources()).thenReturn(resourceResponseList); + List schemaDataResponseList = getSchemaDataResponseList("test1", "test2", "test3"); + when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(schemaDataResponseList); - // when + // Act List result = resourceTaskService.createTasks(); - // then + // Assert assertEquals(3, result.size()); for(ResourceTask task : result){ - assertEquals(false, task.exists); + assertFalse(task.exists); } } @Test void ResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { - // given - List resourceResponseList = List.of( - new ResourceResponse( - "1", - "Resource", - null, null, null, null, null - ), - new ResourceResponse( - "2", - "Distribution", - null, null, null, null, null + // Arrange + List fdpResourceResponseList = getResourceResponseList(); + List schemaDataResponseList = getSchemaDataResponseList("Resource", "Distribution", "Dataset"); - ), - new ResourceResponse( - "3", - "Dataset", - null, null, null, null, null - - ) - ); - - List schemaDataResponseList = List.of( - new SchemaDataResponse( - "1", - "Resource", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ), - new SchemaDataResponse( - "2", - "Distribution", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ), - new SchemaDataResponse( - "3", - "Dataset", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ) - ); - - when(fdpServiceMock.getAllResources()).thenReturn(resourceResponseList); + when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(schemaDataResponseList); // when @@ -294,170 +196,50 @@ void ResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { // then assertEquals(3, result.size()); for(ResourceTask task : result){ - assertEquals(false, task.exists); + assertFalse(task.exists); } } @Test - void ParentResourceNotInSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo() { - // given - List resourceResponseList = List.of( - new ResourceResponse( - "1", - "Resource", - null, null, null, null, null - ), - new ResourceResponse( - "2", - "Distribution", - null, null, null, null, null + void ParentResourceNotInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo() { + // Arrange + List fdpResourceResponseList = getResourceResponseList(); - ), - new ResourceResponse( - "3", - "Dataset", - null, null, null, null, null + when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); - ) - ); - - when(fdpServiceMock.getAllResources()).thenReturn(resourceResponseList); - - // when + // Act List result = resourceTaskService.createParentTasks(); - // then + // Assert assertEquals(3, result.size()); for(ResourceTask task : result){ - assertEquals(false, task.exists); + assertFalse(task.exists); } } @Test - void ParentResourceInSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithChildInfo(){ - // given - List resourceResponseList = List.of( - new ResourceResponse( - "1", - "Resource", - null, null, null, null, null - ), - new ResourceResponse( - "2", - "Distribution", - null, null, null, null, null - - ), - new ResourceResponse( - "3", - "Dataset", - null, null, null, null, null - - ) - ); - - List schemaDataResponseList = List.of( - new SchemaDataResponse( - "1", - "Resource", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ), - new SchemaDataResponse( - "2", - "Distribution", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ), - new SchemaDataResponse( - "3", - "Dataset", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ) - ); - - when(fdpServiceMock.getAllResources()).thenReturn(resourceResponseList); + void ParentResourceInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithChildInfo(){ + // Arrange + List fdpResourceResponseList = getResourceResponseList(); + List schemaDataResponseList = getSchemaDataResponseList("Resource", "Distribution", "Dataset"); + when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(schemaDataResponseList); - // when + // Act List result = resourceTaskService.createTasks(); - // then + // Assert assertEquals(3, result.size()); for(ResourceTask task : result){ - assertEquals(false, task.exists); + assertFalse(task.exists); } } @Test void TestResourceTaskService_RealScenario() { - // given - List resourceResponseList = List.of( + // Arrange + List fdpResourceResponseList = List.of( new ResourceResponse( "2f08228e-1789-40f8-84cd-28e3288c3604", "Dataset", @@ -787,15 +569,15 @@ void TestResourceTaskService_RealScenario() { ) ); - when(fdpServiceMock.getAllResources()).thenReturn(resourceResponseList); + when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(schemaDataResponseList); - // when + // Act List result = resourceTaskService.createTasks(); - // then - assertEquals(3, result.size()); // 3 resources defined in properties + // Assert + assertEquals(3, result.size()); for(ResourceTask task : result){ assertEquals(true, task.exists); } From e28bd4910682daed13f1ed9115befa247bc874ff Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Mon, 10 Nov 2025 15:15:59 +0100 Subject: [PATCH 28/51] fix: fixed ResourceTaskService giving incorrect resource task exists --- .../services/ResourceTaskService.java | 22 ++++++------ .../services/ResourceTaskServiceTest.java | 36 +++++++++---------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index 79bc9ed..d38f357 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -29,11 +29,11 @@ public ResourceTaskService(FdpServiceInterface fdpService, Properties properties } public List createTasks() { - List resourceResponseList = this.fdpService.getAllResources(); - Map resourceInfoMap = createResourceInfoMap(resourceResponseList); + List fdpResourceResponseList = this.fdpService.getAllResources(); + Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); - List schemaDataResponseList = this.fdpService.getAllSchemas(); - Map schemaInfoMap = createSchemaInfoMap(schemaDataResponseList); + List fdpSchemaDataResponseList = this.fdpService.getAllSchemas(); + Map fdpSchemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); // Build and validate ResourceTasks @@ -43,7 +43,7 @@ public List createTasks() { String schemaUUID = ""; boolean exists = false; - ResourceInfo fdpResourceInfo = resourceInfoMap.get(resourceName); + ResourceInfo fdpResourceInfo = fdpResourceInfoMap.get(resourceName); if(fdpResourceInfo != null){ resourceUuid = fdpResourceInfo.uuid(); exists = true; @@ -52,9 +52,9 @@ public List createTasks() { String schema = entry.getValue().schema(); String name = schema.isBlank() ? resourceName : schema; - SchemaInfo schemaInfo = schemaInfoMap.get(name); + SchemaInfo schemaInfo = fdpSchemaInfoMap.get(name); if(schemaInfo != null){ - schemaUUID = schemaInfoMap.get(name).uuid(); + schemaUUID = fdpSchemaInfoMap.get(name).uuid(); } return new ResourceTask( @@ -67,8 +67,8 @@ public List createTasks() { } public List createParentTasks() { - List resourceResponseList = this.fdpService.getAllResources(); - Map resourceInfoMap = createResourceInfoMap(resourceResponseList); + List fdpResourceResponseList = this.fdpService.getAllResources(); + Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); return this.properties.resources.entrySet().stream().map(entry -> { String parentResourceName = entry.getValue().parentResource(); @@ -78,12 +78,12 @@ public List createParentTasks() { String childUuid = null; boolean exists = false; - ResourceInfo fdpResourceInfo = resourceInfoMap.get(parentResourceName); + ResourceInfo fdpResourceInfo = fdpResourceInfoMap.get(parentResourceName); if(fdpResourceInfo != null){ parentResourceUuid = fdpResourceInfo.uuid(); childName = entry.getKey(); childIri = entry.getValue().parentRelationIri(); - childUuid = resourceInfoMap.get(parentResourceName).uuid(); + childUuid = fdpResourceInfoMap.get(parentResourceName).uuid(); } ResourceTask resourceTask = new ResourceTask( diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index 61a31dd..31a2202 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -4,6 +4,7 @@ import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -25,7 +26,7 @@ class ResourceTaskServiceTest { @BeforeEach void setUp() { - MockitoAnnotations.openMocks(this); + fdpServiceMock = mock(FdpService.class); getProperties(); resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); } @@ -52,22 +53,22 @@ private void getProperties() { this.properties = properties; } - List getResourceResponseList() { + List getResourceResponseList(String name1, String name2, String name3) { return List.of( new ResourceResponse( "1", - "Resource", + name1, null, null, null, null, null ), new ResourceResponse( "2", - "Distribution", + name2, null, null, null, null, null ), new ResourceResponse( "3", - "Dataset", + name3, null, null, null, null, null ) @@ -163,8 +164,7 @@ List getSchemaDataResponseList(String name1, String name2, S @Test void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() { // Arrange - List fdpResourceResponseList = getResourceResponseList(); - + List fdpResourceResponseList = getResourceResponseList("test1", "test2", "test3"); List schemaDataResponseList = getSchemaDataResponseList("test1", "test2", "test3"); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); @@ -183,27 +183,27 @@ void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() @Test void ResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { // Arrange - List fdpResourceResponseList = getResourceResponseList(); - List schemaDataResponseList = getSchemaDataResponseList("Resource", "Distribution", "Dataset"); + List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); + List fdpSchemaDataResponseList = getSchemaDataResponseList("Resource", "Distribution", "Dataset"); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); - when(fdpServiceMock.getAllSchemas()).thenReturn(schemaDataResponseList); + when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); - // when + // Act List result = resourceTaskService.createTasks(); - // then + // Assert assertEquals(3, result.size()); for(ResourceTask task : result){ - assertFalse(task.exists); + assertTrue(task.exists); } } @Test - void ParentResourceNotInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo() { + void ParentResourceNotFoundInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo() { // Arrange - List fdpResourceResponseList = getResourceResponseList(); + List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); @@ -218,9 +218,9 @@ void ParentResourceNotInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceW } @Test - void ParentResourceInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithChildInfo(){ + void ParentResourceFoundInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithChildInfo(){ // Arrange - List fdpResourceResponseList = getResourceResponseList(); + List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); List schemaDataResponseList = getSchemaDataResponseList("Resource", "Distribution", "Dataset"); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); @@ -232,7 +232,7 @@ void ParentResourceInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWith // Assert assertEquals(3, result.size()); for(ResourceTask task : result){ - assertFalse(task.exists); + assertTrue(task.exists); } } From 209c7afad7a609732c09eea1fc203a03a390285b Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Mon, 10 Nov 2025 16:39:20 +0100 Subject: [PATCH 29/51] fix: fixed properties file for tests and added more asserts for task.resource, task.uuid and task.shapeUUUID --- .../services/ResourceTaskService.java | 9 ++- .../services/ResourceTaskServiceTest.java | 73 ++++++++++++++++--- 2 files changed, 67 insertions(+), 15 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index d38f357..b32d2a0 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -39,19 +39,20 @@ public List createTasks() { // Build and validate ResourceTasks return properties.resources.entrySet().stream().map(entry -> { String resourceName = entry.getKey(); - String resourceUuid = ""; + String resourceUUID = ""; String schemaUUID = ""; boolean exists = false; + // Sets resourceUUID and exists from resource in FDP if exists in fdpResourceInfoMap ResourceInfo fdpResourceInfo = fdpResourceInfoMap.get(resourceName); if(fdpResourceInfo != null){ - resourceUuid = fdpResourceInfo.uuid(); + resourceUUID = fdpResourceInfo.uuid(); exists = true; } + // Sets schemaUUID from schema in FDP if property resource name exists in fdpSchemaInfoMap String schema = entry.getValue().schema(); String name = schema.isBlank() ? resourceName : schema; - SchemaInfo schemaInfo = fdpSchemaInfoMap.get(name); if(schemaInfo != null){ schemaUUID = fdpSchemaInfoMap.get(name).uuid(); @@ -59,7 +60,7 @@ public List createTasks() { return new ResourceTask( resourceName, - resourceUuid, + resourceUUID, schemaUUID, exists ); diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index 31a2202..ac95360 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -4,12 +4,10 @@ import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; -import org.mockito.MockitoAnnotations; import java.util.ArrayList; import java.util.List; @@ -34,9 +32,9 @@ void setUp() { private void getProperties() { Properties properties = new Properties(); + properties.schemas.put("Catalog", List.of("Catalog.ttl", "Agent.ttl", "Kind.ttl")); + properties.schemas.put("Dataset", List.of("Dataset.ttl", "Agent.ttl", "Kind.ttl","PeriodOfTime.ttl","Attribution.ttl","Identifier.ttl","QualityCertificate.ttl","Relationship.ttl")); properties.schemas.put("Resource", List.of("Resource.ttl")); - properties.schemas.put("Distribution", List.of("Distribution.ttl", "PeriodOfTime.ttl", "Checksum.ttl")); - properties.schemas.put("Dataset", List.of("Dataset.ttl", "Agent.ttl", "Kind.ttl")); properties.parentChild.put("Resource", List.of("Dataset", "Catalog", "Data Service")); @@ -162,13 +160,36 @@ List getSchemaDataResponseList(String name1, String name2, S } @Test - void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() { + void PropertyResourceNotInFdpSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() { // Arrange List fdpResourceResponseList = getResourceResponseList("test1", "test2", "test3"); - List schemaDataResponseList = getSchemaDataResponseList("test1", "test2", "test3"); + List fdpSchemaDataResponseList = getSchemaDataResponseList("test1", "test2", "test3"); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); - when(fdpServiceMock.getAllSchemas()).thenReturn(schemaDataResponseList); + when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); + + // Act + List result = resourceTaskService.createTasks(); + + // Assert + assertEquals(3, result.size()); + for (ResourceTask task : result) { + assertEquals("", task.resource); // should be same as in properties file + assertEquals("", task.UUID); + assertEquals("", task.shapeUUUID); + assertFalse(task.exists); + } + } + + @Test + void PropertyResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { + // Arrange + List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); + List fdpSchemaDataResponseList = getSchemaDataResponseList("Resource", "Distribution", "Dataset"); + + + when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); + when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); // Act List result = resourceTaskService.createTasks(); @@ -176,12 +197,39 @@ void ResourceNotInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() // Assert assertEquals(3, result.size()); for(ResourceTask task : result){ + assertEquals("", task.resource); // should be same as in properties file + assertEquals("", task.UUID); + assertEquals("", task.shapeUUUID); assertFalse(task.exists); } } + // todo + @Test + void PropertyResourceNotInFdpResourceInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() { + // Arrange + List fdpResourceResponseList = getResourceResponseList("test1", "test2", "test3"); + List fdpSchemaDataResponseList = getSchemaDataResponseList("test1", "test2", "test3"); + + when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); + when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); + + // Act + List result = resourceTaskService.createTasks(); + + // Assert + assertEquals(3, result.size()); + for (ResourceTask task : result) { + assertEquals("", task.resource); // should be same as in properties file + assertEquals("", task.UUID); // should be empty because resource is not in fdpResourceInfoMap and so set to empty string + assertEquals("", task.shapeUUUID); + assertFalse(task.exists); // should be false because its in fdpResourceInfoMap + } + } + + // todo @Test - void ResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { + void PropertyResourceInFdpResourceInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { // Arrange List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); List fdpSchemaDataResponseList = getSchemaDataResponseList("Resource", "Distribution", "Dataset"); @@ -196,12 +244,15 @@ void ResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { // Assert assertEquals(3, result.size()); for(ResourceTask task : result){ - assertTrue(task.exists); + assertEquals("", task.resource); // should be same as in properties file + assertEquals("", task.UUID); // should be resource.uuid from fdpResourceInfoMap + assertEquals("", task.shapeUUUID); + assertTrue(task.exists); // should be true because its in fdpResourceInfoMap } } @Test - void ParentResourceNotFoundInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo() { + void PropertyParentResourceNotFoundInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo() { // Arrange List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); @@ -218,7 +269,7 @@ void ParentResourceNotFoundInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnReso } @Test - void ParentResourceFoundInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithChildInfo(){ + void PropertyParentResourceFoundInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithChildInfo(){ // Arrange List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); List schemaDataResponseList = getSchemaDataResponseList("Resource", "Distribution", "Dataset"); From 9afba255e54a691bb4c5efc823fff1f7353d1067 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Tue, 11 Nov 2025 12:01:24 +0100 Subject: [PATCH 30/51] refactor: Split getSchemaUUID and getResourceInfo functions from createResourceTasks and added tests for these functions --- .../services/ResourceTaskService.java | 49 ++++--- .../services/ResourceTaskServiceTest.java | 123 +++++++++++++----- 2 files changed, 119 insertions(+), 53 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index b32d2a0..b10fe4e 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -1,5 +1,6 @@ package nl.healthri.fdp.uploadschema.services; +import jakarta.annotation.Resource; import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; @@ -21,6 +22,7 @@ public class ResourceTaskService implements ResourceTaskServiceInterface { public FdpServiceInterface fdpService; public Properties properties; + private static final Logger logger = LoggerFactory.getLogger(ResourceTaskService.class); public ResourceTaskService(FdpServiceInterface fdpService, Properties properties) { @@ -39,30 +41,14 @@ public List createTasks() { // Build and validate ResourceTasks return properties.resources.entrySet().stream().map(entry -> { String resourceName = entry.getKey(); - String resourceUUID = ""; - String schemaUUID = ""; - boolean exists = false; - - // Sets resourceUUID and exists from resource in FDP if exists in fdpResourceInfoMap - ResourceInfo fdpResourceInfo = fdpResourceInfoMap.get(resourceName); - if(fdpResourceInfo != null){ - resourceUUID = fdpResourceInfo.uuid(); - exists = true; - } - - // Sets schemaUUID from schema in FDP if property resource name exists in fdpSchemaInfoMap - String schema = entry.getValue().schema(); - String name = schema.isBlank() ? resourceName : schema; - SchemaInfo schemaInfo = fdpSchemaInfoMap.get(name); - if(schemaInfo != null){ - schemaUUID = fdpSchemaInfoMap.get(name).uuid(); - } + ResourceData resourceData = getResourceInfo(resourceName, fdpResourceInfoMap); + String schemaUUID = getSchemaUUID(resourceName, entry.getValue().schema(), fdpSchemaInfoMap); return new ResourceTask( resourceName, - resourceUUID, + resourceData.resourceUUID, schemaUUID, - exists + resourceData.exists ); }).toList(); } @@ -97,4 +83,27 @@ public List createParentTasks() { return resourceTask; }).toList(); } + + protected record ResourceData(String resourceUUID, boolean exists) {} + + protected ResourceData getResourceInfo(String resourceName, Map fdpResourceInfoMap) { + ResourceInfo fdpResourceInfo = fdpResourceInfoMap.get(resourceName); + + if (fdpResourceInfo == null) { + return new ResourceData("", false); + } + + return new ResourceData(fdpResourceInfo.uuid(), true); + } + + protected String getSchemaUUID(String resourceName, String schema, Map fdpSchemaInfoMap) { + String name = (schema == null || schema.isBlank()) ? resourceName : schema; + + SchemaInfo schemaInfo = fdpSchemaInfoMap.get(name); + if (schemaInfo == null) { + return ""; + } + + return schemaInfo.uuid(); + } } diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index ac95360..1548d44 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -5,13 +5,18 @@ import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.utils.Properties; +import nl.healthri.fdp.uploadschema.utils.ResourceInfo; +import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import static nl.healthri.fdp.uploadschema.utils.ResourceInfo.createResourceInfoMap; +import static nl.healthri.fdp.uploadschema.utils.SchemaInfo.createSchemaInfoMap; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @@ -39,11 +44,11 @@ private void getProperties() { properties.parentChild.put("Resource", List.of("Dataset", "Catalog", "Data Service")); properties.resources.put("Sample Distribution", - new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/adms#sample", "Distribution")); + new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/adms#sample", "Catalog")); properties.resources.put("Dataset Series", - new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/dcat#inSeries", "Dataset Series")); + new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/dcat#inSeries", "Dataset")); properties.resources.put("Analytics Distribution", - new Properties.ResourceProperties("Dataset", "http://healthdataportal.eu/ns/health#analytics", "Distribution")); + new Properties.ResourceProperties("Dataset", "http://healthdataportal.eu/ns/health#analytics", "Resource")); properties.schemasToPublish = List.of("Resource", "Catalog", "Dataset", "Dataset Series", "Distribution", "Data Service"); properties.schemaVersion = "2.0.0"; @@ -159,34 +164,82 @@ List getSchemaDataResponseList(String name1, String name2, S ); } + @Test - void PropertyResourceNotInFdpSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() { + void PropertyResourceNotFoundInFdpResourceInfoMap_WhenGettingResourceInfo_ResourceDataEmptyIdAndExistsFalse() { // Arrange - List fdpResourceResponseList = getResourceResponseList("test1", "test2", "test3"); - List fdpSchemaDataResponseList = getSchemaDataResponseList("test1", "test2", "test3"); + List fdpResourceResponseList = getResourceResponseList("resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); + Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); + + // Act & Assert + this.properties.resources.entrySet().forEach(propertyResource -> { + ResourceTaskService.ResourceData resourceData = + this.resourceTaskService.getResourceInfo(propertyResource.getKey(), fdpResourceInfoMap); + + // Assert + assertEquals("", resourceData.resourceUUID()); + assertFalse(resourceData.exists()); + }); + } + + @Test + void PropertyResourceFoundInFdpResourceInfoMap_WhenGettingResourceInfo_ResourceDataIdIsFdpUuidIdAndExistsTrue() { + // Arrange + List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); + Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); + + // Act & Assert + this.properties.resources.entrySet().forEach(propertyResource -> { + ResourceTaskService.ResourceData resourceData = + this.resourceTaskService.getResourceInfo(propertyResource.getKey(), fdpResourceInfoMap); + + // Assert + String fdpResourceUuid = fdpResourceInfoMap.get(propertyResource.getKey()).uuid(); + assertEquals(fdpResourceUuid, resourceData.resourceUUID()); + assertTrue(resourceData.exists()); + }); + } + + @Test + void PropertyResourceNotFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsEmptyId() { + // Arrange + List fdpSchemaDataResponseList = getSchemaDataResponseList("resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); + Map fdpSchemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); - when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); - // Act - List result = resourceTaskService.createTasks(); + // Act & Assert + this.properties.resources.entrySet().forEach(propertyResource -> { + String resourceSchemaId = this.resourceTaskService.getSchemaUUID(propertyResource.getKey(), propertyResource.getValue().schema(), fdpSchemaInfoMap); - // Assert - assertEquals(3, result.size()); - for (ResourceTask task : result) { - assertEquals("", task.resource); // should be same as in properties file - assertEquals("", task.UUID); - assertEquals("", task.shapeUUUID); - assertFalse(task.exists); - } + // Assert + assertEquals("", resourceSchemaId); + }); } @Test - void PropertyResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { + void PropertyResourceFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsSchemaIdFromFdpSchema() { // Arrange - List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); - List fdpSchemaDataResponseList = getSchemaDataResponseList("Resource", "Distribution", "Dataset"); + List fdpSchemaDataResponseList = getSchemaDataResponseList("Catalog", "Dataset", "Resource"); + Map fdpSchemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); + + when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); + + // Act & Assert + this.properties.resources.entrySet().forEach(propertyResource -> { + String resourceSchemaId = this.resourceTaskService.getSchemaUUID(propertyResource.getKey(), propertyResource.getValue().schema(), fdpSchemaInfoMap); + String expectedSchemaId = fdpSchemaInfoMap.get(propertyResource.getValue().schema()).uuid(); + // Assert + assertEquals(expectedSchemaId, resourceSchemaId); + }); + } + + @Test + void PropertyResourceNotInFdpSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() { + // Arrange + List fdpResourceResponseList = getResourceResponseList("test1", "test2", "test3"); + List fdpSchemaDataResponseList = getSchemaDataResponseList("test1", "test2", "test3"); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); @@ -196,7 +249,8 @@ void PropertyResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTr // Assert assertEquals(3, result.size()); - for(ResourceTask task : result){ + for (ResourceTask task : result) { + properties.resources.get(task.resource); assertEquals("", task.resource); // should be same as in properties file assertEquals("", task.UUID); assertEquals("", task.shapeUUUID); @@ -204,9 +258,8 @@ void PropertyResourceInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTr } } - // todo @Test - void PropertyResourceNotInFdpResourceInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() { + void PropertyResourceNotInFdpSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse2() { // Arrange List fdpResourceResponseList = getResourceResponseList("test1", "test2", "test3"); List fdpSchemaDataResponseList = getSchemaDataResponseList("test1", "test2", "test3"); @@ -220,16 +273,16 @@ void PropertyResourceNotInFdpResourceInfoMap_WhenCreatingTasks_ReturnResourceWit // Assert assertEquals(3, result.size()); for (ResourceTask task : result) { + properties.resources.get(task.resource); assertEquals("", task.resource); // should be same as in properties file - assertEquals("", task.UUID); // should be empty because resource is not in fdpResourceInfoMap and so set to empty string + assertEquals("", task.UUID); assertEquals("", task.shapeUUUID); - assertFalse(task.exists); // should be false because its in fdpResourceInfoMap + assertFalse(task.exists); } } - // todo @Test - void PropertyResourceInFdpResourceInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { + void PropertyResourceFoundInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { // Arrange List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); List fdpSchemaDataResponseList = getSchemaDataResponseList("Resource", "Distribution", "Dataset"); @@ -243,14 +296,18 @@ void PropertyResourceInFdpResourceInfoMap_WhenCreatingTasks_ReturnResourceWithEx // Assert assertEquals(3, result.size()); - for(ResourceTask task : result){ - assertEquals("", task.resource); // should be same as in properties file - assertEquals("", task.UUID); // should be resource.uuid from fdpResourceInfoMap - assertEquals("", task.shapeUUUID); - assertTrue(task.exists); // should be true because its in fdpResourceInfoMap - } + result.stream().forEach(task -> { + Properties.ResourceProperties propertyResource = properties.resources.get(task.resource); + assertEquals(propertyResource.schema(), task.resource); + assertEquals("", task.UUID); + assertEquals("", task.shapeUUUID); + assertFalse(task.exists); + }); + } + // todo: add 2 more tests here + @Test void PropertyParentResourceNotFoundInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo() { // Arrange From e028a02712acb3d6307e8a16e1351ec07ecc7b8d Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Tue, 11 Nov 2025 16:27:07 +0100 Subject: [PATCH 31/51] Fix: fixed getParentResourceInfo giving the correct childUuid --- .../fdp/uploadschema/domain/ResourceTask.java | 8 ++- .../services/ResourceTaskService.java | 71 ++++++++++++------- .../services/ResourceTaskServiceTest.java | 4 ++ 3 files changed, 55 insertions(+), 28 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java b/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java index b2018c7..127288e 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java @@ -16,7 +16,6 @@ public class ResourceTask { private static final Logger logger = LoggerFactory.getLogger(ResourceTask.class); - public ResourceTask(String resource, String uuid, String shapeUUUID, boolean exists) { this.resource = resource; this.UUID = uuid; @@ -24,11 +23,14 @@ public ResourceTask(String resource, String uuid, String shapeUUUID, boolean exi this.exists = exists; } - - public void addChildInfo(String childUUuid, String childRelationIri, String childName) { + public ResourceTask(String resource, String uuid, String shapeUUUID, String childUUuid, String childRelationIri, String childName, boolean exists) { + this.resource = resource; + this.UUID = uuid; + this.shapeUUUID = shapeUUUID; this.childUUuid = childUUuid; this.childRelationIri = childRelationIri; this.childName = childName; + this.exists = exists; } public void validate() { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index b10fe4e..506b910 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -39,10 +39,10 @@ public List createTasks() { // Build and validate ResourceTasks - return properties.resources.entrySet().stream().map(entry -> { - String resourceName = entry.getKey(); + return properties.resources.entrySet().stream().map(propertyResource -> { + String resourceName = propertyResource.getKey(); ResourceData resourceData = getResourceInfo(resourceName, fdpResourceInfoMap); - String schemaUUID = getSchemaUUID(resourceName, entry.getValue().schema(), fdpSchemaInfoMap); + String schemaUUID = getSchemaUUID(resourceName, propertyResource.getValue().schema(), fdpSchemaInfoMap); return new ResourceTask( resourceName, @@ -57,33 +57,54 @@ public List createParentTasks() { List fdpResourceResponseList = this.fdpService.getAllResources(); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); - return this.properties.resources.entrySet().stream().map(entry -> { - String parentResourceName = entry.getValue().parentResource(); - String parentResourceUuid = ""; - String childName = null; - String childIri = null; - String childUuid = null; - boolean exists = false; - - ResourceInfo fdpResourceInfo = fdpResourceInfoMap.get(parentResourceName); - if(fdpResourceInfo != null){ - parentResourceUuid = fdpResourceInfo.uuid(); - childName = entry.getKey(); - childIri = entry.getValue().parentRelationIri(); - childUuid = fdpResourceInfoMap.get(parentResourceName).uuid(); - } - - ResourceTask resourceTask = new ResourceTask( - parentResourceName, - parentResourceUuid, + return this.properties.resources.entrySet().stream().map(propertyResource -> { + ParentResourceData parentResourceData = getParentResourceInfo(propertyResource, fdpResourceInfoMap); + + return new ResourceTask( + parentResourceData.parentResourceName, + parentResourceData.parentResourceUuid, null, - exists + parentResourceData.childUuid, + parentResourceData.childIri, + parentResourceData.childName, + parentResourceData.exists ); - resourceTask.addChildInfo(childUuid, childIri, childName); - return resourceTask; }).toList(); } + protected record ParentResourceData( + String parentResourceName, + String parentResourceUuid, + String childUuid, + String childIri, + String childName, + boolean exists + ) {} + + protected ParentResourceData getParentResourceInfo(Map.Entry entry, Map fdpResourceInfoMap) { + String parentResourceName = entry.getValue().parentResource(); + + ResourceInfo fdpResourceInfo = fdpResourceInfoMap.get(parentResourceName); + if (fdpResourceInfo == null) { + return new ParentResourceData(parentResourceName, null, null, null, null, false); + } + + String parentResourceUuid = fdpResourceInfo.uuid(); + String childName = entry.getKey(); + String childIri = entry.getValue().parentRelationIri(); + String childUuid = fdpResourceInfoMap.get(childName).uuid(); + boolean exists = true; + + return new ParentResourceData( + parentResourceName, + parentResourceUuid, + childUuid, + childIri, + childName, + exists); + } + + protected record ResourceData(String resourceUUID, boolean exists) {} protected ResourceData getResourceInfo(String resourceName, Map fdpResourceInfoMap) { diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index 1548d44..1568a9f 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -235,6 +235,10 @@ void PropertyResourceFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsSchema }); } + // createParentsgood + // createParentsntogood + // createtasksgood + // createtasksnotgood @Test void PropertyResourceNotInFdpSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() { // Arrange From 026e55b936a04dd0622a9dd923adbe0b627e8aae Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Tue, 11 Nov 2025 16:30:21 +0100 Subject: [PATCH 32/51] refactor: moved records used by ResourceTaskService to the top of the file --- .../services/ResourceTaskService.java | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index 506b910..87a9bc5 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -30,6 +30,19 @@ public ResourceTaskService(FdpServiceInterface fdpService, Properties properties this.properties = properties; } + protected record ResourceData( + String resourceUUID, + boolean exists) {} + + protected record ParentResourceData( + String parentResourceName, + String parentResourceUuid, + String childUuid, + String childIri, + String childName, + boolean exists) {} + + public List createTasks() { List fdpResourceResponseList = this.fdpService.getAllResources(); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); @@ -72,15 +85,6 @@ public List createParentTasks() { }).toList(); } - protected record ParentResourceData( - String parentResourceName, - String parentResourceUuid, - String childUuid, - String childIri, - String childName, - boolean exists - ) {} - protected ParentResourceData getParentResourceInfo(Map.Entry entry, Map fdpResourceInfoMap) { String parentResourceName = entry.getValue().parentResource(); @@ -104,9 +108,6 @@ protected ParentResourceData getParentResourceInfo(Map.Entry fdpResourceInfoMap) { ResourceInfo fdpResourceInfo = fdpResourceInfoMap.get(resourceName); From ed18c03b739e6016fb76b7e5324b2924c9076af7 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Wed, 12 Nov 2025 10:06:42 +0100 Subject: [PATCH 33/51] feature: Added tests for getParentResourceInfo --- .../services/ResourceTaskService.java | 15 +- .../services/ResourceTaskServiceTest.java | 136 +++++++++--------- 2 files changed, 77 insertions(+), 74 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index 87a9bc5..9a5f31d 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -85,22 +85,23 @@ public List createParentTasks() { }).toList(); } - protected ParentResourceData getParentResourceInfo(Map.Entry entry, Map fdpResourceInfoMap) { - String parentResourceName = entry.getValue().parentResource(); + // Gets information from property resource parent and creates a new parent resource with parent information. + protected ParentResourceData getParentResourceInfo(Map.Entry propertyResource, Map fdpResourceInfoMap) { + String propertyResourceParentName = propertyResource.getValue().parentResource(); - ResourceInfo fdpResourceInfo = fdpResourceInfoMap.get(parentResourceName); + ResourceInfo fdpResourceInfo = fdpResourceInfoMap.get(propertyResourceParentName); if (fdpResourceInfo == null) { - return new ParentResourceData(parentResourceName, null, null, null, null, false); + return new ParentResourceData(propertyResourceParentName, null, null, null, null, false); } String parentResourceUuid = fdpResourceInfo.uuid(); - String childName = entry.getKey(); - String childIri = entry.getValue().parentRelationIri(); + String childName = propertyResource.getKey(); + String childIri = propertyResource.getValue().parentRelationIri(); String childUuid = fdpResourceInfoMap.get(childName).uuid(); boolean exists = true; return new ParentResourceData( - parentResourceName, + propertyResourceParentName, parentResourceUuid, childUuid, childIri, diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index 1568a9f..24122e8 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -7,6 +7,7 @@ import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.ResourceInfo; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; +import org.apache.poi.poifs.property.Parent; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; @@ -44,11 +45,11 @@ private void getProperties() { properties.parentChild.put("Resource", List.of("Dataset", "Catalog", "Data Service")); properties.resources.put("Sample Distribution", - new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/adms#sample", "Catalog")); + new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/adms#sample", "Distribution")); properties.resources.put("Dataset Series", - new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/dcat#inSeries", "Dataset")); + new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/dcat#inSeries", "Dataset Series")); properties.resources.put("Analytics Distribution", - new Properties.ResourceProperties("Dataset", "http://healthdataportal.eu/ns/health#analytics", "Resource")); + new Properties.ResourceProperties("Dataset", "http://healthdataportal.eu/ns/health#analytics", "Distribution")); properties.schemasToPublish = List.of("Resource", "Catalog", "Dataset", "Dataset Series", "Distribution", "Data Service"); properties.schemaVersion = "2.0.0"; @@ -78,6 +79,32 @@ List getResourceResponseList(String name1, String name2, Strin ); } + List getResourceResponseListWithParent(String name1, String name2, String name3, String name4) { + return List.of( + new ResourceResponse( + "1", + name1, + null, null, null, null, null + ), + new ResourceResponse( + "2", + name2, + null, null, null, null, null + + ), + new ResourceResponse( + "3", + name3, + null, null, null, null, null + ), + new ResourceResponse( + "4", + name4, + null, null, null, null, null + ) + ); + } + List getSchemaDataResponseList(String name1, String name2, String name3) { return List.of( new SchemaDataResponse( @@ -210,6 +237,7 @@ void PropertyResourceNotFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsEmp // Act & Assert this.properties.resources.entrySet().forEach(propertyResource -> { + // Act String resourceSchemaId = this.resourceTaskService.getSchemaUUID(propertyResource.getKey(), propertyResource.getValue().schema(), fdpSchemaInfoMap); // Assert @@ -227,90 +255,64 @@ void PropertyResourceFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsSchema // Act & Assert this.properties.resources.entrySet().forEach(propertyResource -> { + // Act String resourceSchemaId = this.resourceTaskService.getSchemaUUID(propertyResource.getKey(), propertyResource.getValue().schema(), fdpSchemaInfoMap); - String expectedSchemaId = fdpSchemaInfoMap.get(propertyResource.getValue().schema()).uuid(); // Assert + String expectedSchemaId = fdpSchemaInfoMap.get(propertyResource.getValue().schema()).uuid(); assertEquals(expectedSchemaId, resourceSchemaId); }); } - // createParentsgood - // createParentsntogood - // createtasksgood - // createtasksnotgood @Test - void PropertyResourceNotInFdpSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse() { + void PropertyParentResourceNotFoundInFdpResourceInfoMap_WhenGettingParentResourceInfo_ReturnEmptyParentResourceData(){ // Arrange - List fdpResourceResponseList = getResourceResponseList("test1", "test2", "test3"); - List fdpSchemaDataResponseList = getSchemaDataResponseList("test1", "test2", "test3"); - - when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); - when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); - - // Act - List result = resourceTaskService.createTasks(); - - // Assert - assertEquals(3, result.size()); - for (ResourceTask task : result) { - properties.resources.get(task.resource); - assertEquals("", task.resource); // should be same as in properties file - assertEquals("", task.UUID); - assertEquals("", task.shapeUUUID); - assertFalse(task.exists); - } - } - - @Test - void PropertyResourceNotInFdpSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistFalse2() { - // Arrange - List fdpResourceResponseList = getResourceResponseList("test1", "test2", "test3"); - List fdpSchemaDataResponseList = getSchemaDataResponseList("test1", "test2", "test3"); - - when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); - when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); + List fdpResourceResponseList = getResourceResponseListWithParent("parent-resource-not-in-fdp", "resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); + Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); - // Act - List result = resourceTaskService.createTasks(); + // Act & Assert + this.properties.resources.entrySet().forEach(propertyResource -> { + ResourceTaskService.ParentResourceData resourceData = + this.resourceTaskService.getParentResourceInfo(propertyResource, fdpResourceInfoMap); - // Assert - assertEquals(3, result.size()); - for (ResourceTask task : result) { - properties.resources.get(task.resource); - assertEquals("", task.resource); // should be same as in properties file - assertEquals("", task.UUID); - assertEquals("", task.shapeUUUID); - assertFalse(task.exists); - } + // Assert + assertEquals(propertyResource.getValue().parentResource(), resourceData.parentResourceName()); + assertNull(resourceData.parentResourceUuid()); + assertNull(resourceData.childUuid()); + assertNull(resourceData.childIri()); + assertNull(resourceData.childName()); + assertFalse(resourceData.exists()); + }); } + // TODO: @Test - void PropertyResourceFoundInSchemaInfoMap_WhenCreatingTasks_ReturnResourceWithExistTrue() { + void PropertyParentResourceFoundInFdpResourceInfoMap_WhenGettingParentResourceInfo_ReturnParentResourceDataWithFilledChildInfo(){ // Arrange - List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); - List fdpSchemaDataResponseList = getSchemaDataResponseList("Resource", "Distribution", "Dataset"); - - - when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); - when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); + List fdpResourceResponseList = getResourceResponseListWithParent("Dataset", "Sample Distribution", "Dataset Series", "Analytics Distribution"); + Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); - // Act - List result = resourceTaskService.createTasks(); + // Act & Assert + this.properties.resources.entrySet().forEach(propertyResource -> { + ResourceTaskService.ParentResourceData resourceData = + this.resourceTaskService.getParentResourceInfo(propertyResource, fdpResourceInfoMap); - // Assert - assertEquals(3, result.size()); - result.stream().forEach(task -> { - Properties.ResourceProperties propertyResource = properties.resources.get(task.resource); - assertEquals(propertyResource.schema(), task.resource); - assertEquals("", task.UUID); - assertEquals("", task.shapeUUUID); - assertFalse(task.exists); + // Assert + String parentResource = propertyResource.getValue().parentResource(); + assertEquals(parentResource, resourceData.parentResourceName()); + assertNotNull(resourceData.parentResourceUuid()); + assertNotNull(resourceData.childUuid()); + assertEquals(propertyResource.getValue().parentRelationIri(), resourceData.childIri()); + assertEquals(propertyResource.getKey(), resourceData.childName()); + assertTrue(resourceData.exists()); }); - } - // todo: add 2 more tests here + // TODO: + // createParentsgood + // createParentsntogood + // createtasksgood + // createtasksnotgood @Test void PropertyParentResourceNotFoundInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo() { From 04a74517697b0f97ca07578a83c28bec691aa782 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Wed, 12 Nov 2025 11:37:19 +0100 Subject: [PATCH 34/51] fix: added multiple properties data getters for better testing across multiple scenarios --- .../fdp/uploadschema/domain/ResourceTask.java | 4 +- .../services/ResourceTaskService.java | 7 +- .../services/ShapeTaskService.java | 20 +-- .../services/ResourceTaskServiceTest.java | 114 ++++++++++++------ 4 files changed, 96 insertions(+), 49 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java b/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java index 127288e..0db6047 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/domain/ResourceTask.java @@ -8,11 +8,11 @@ public class ResourceTask { public final String resource; public String UUID; - public String shapeUUUID; + public final String shapeUUUID; public String childUUuid; public String childRelationIri; public String childName; - public boolean exists; + public final boolean exists; private static final Logger logger = LoggerFactory.getLogger(ResourceTask.class); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index 9a5f31d..de50471 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -50,10 +50,10 @@ public List createTasks() { List fdpSchemaDataResponseList = this.fdpService.getAllSchemas(); Map fdpSchemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); - - // Build and validate ResourceTasks return properties.resources.entrySet().stream().map(propertyResource -> { String resourceName = propertyResource.getKey(); + + // Gets all needed resource information from fdpResourceInfoMap to set to new resourceTask ResourceData resourceData = getResourceInfo(resourceName, fdpResourceInfoMap); String schemaUUID = getSchemaUUID(resourceName, propertyResource.getValue().schema(), fdpSchemaInfoMap); @@ -71,6 +71,7 @@ public List createParentTasks() { Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); return this.properties.resources.entrySet().stream().map(propertyResource -> { + // Gets all needed parent resource information from fdpResourceInfoMap to set to new resourceTask ParentResourceData parentResourceData = getParentResourceInfo(propertyResource, fdpResourceInfoMap); return new ResourceTask( @@ -111,7 +112,6 @@ protected ParentResourceData getParentResourceInfo(Map.Entry fdpResourceInfoMap) { ResourceInfo fdpResourceInfo = fdpResourceInfoMap.get(resourceName); - if (fdpResourceInfo == null) { return new ResourceData("", false); } @@ -121,7 +121,6 @@ protected ResourceData getResourceInfo(String resourceName, Map fdpSchemaInfoMap) { String name = (schema == null || schema.isBlank()) ? resourceName : schema; - SchemaInfo schemaInfo = fdpSchemaInfoMap.get(name); if (schemaInfo == null) { return ""; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java index 49afb75..eb23e74 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java @@ -45,6 +45,7 @@ public List createTasks() { Version requestedVersion = this.properties.getVersion(); Set parents = this.properties.getParents(schemaTitle); + // Adds shape task are same or need to be updated if (shapesOnFdp.containsKey(schemaTitle)) { SchemaInfo matchingFdpSchema = shapesOnFdp.get(schemaTitle); Version version = matchingFdpSchema.version().next(requestedVersion); @@ -60,16 +61,17 @@ public List createTasks() { model, status ); - } else { - return new ShapeTask( - schemaTitle, - requestedVersion, - "", - parents, - model, - ShapeStatus.INSERT - ); } + + // Adds shape task to insert into FDP + return new ShapeTask( + schemaTitle, + requestedVersion, + "", + parents, + model, + ShapeStatus.INSERT + ); }).toList(); } } diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index 24122e8..abddcae 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -7,7 +7,6 @@ import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.ResourceInfo; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; -import org.apache.poi.poifs.property.Parent; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; @@ -25,17 +24,15 @@ class ResourceTaskServiceTest { @Mock private FdpService fdpServiceMock; - private Properties properties; private ResourceTaskService resourceTaskService; @BeforeEach void setUp() { fdpServiceMock = mock(FdpService.class); - getProperties(); resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); } - private void getProperties() { + private Properties getTestProperties() { Properties properties = new Properties(); properties.schemas.put("Catalog", List.of("Catalog.ttl", "Agent.ttl", "Kind.ttl")); @@ -44,6 +41,31 @@ private void getProperties() { properties.parentChild.put("Resource", List.of("Dataset", "Catalog", "Data Service")); + properties.resources.put("Sample Distribution", + new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/adms#sample", "Catalog")); + properties.resources.put("Dataset Series", + new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/dcat#inSeries", "Dataset")); + properties.resources.put("Analytics Distribution", + new Properties.ResourceProperties("Dataset", "http://healthdataportal.eu/ns/health#analytics", "Resource")); + + properties.schemasToPublish = List.of("Resource", "Catalog", "Dataset", "Dataset Series", "Distribution", "Data Service"); + properties.schemaVersion = "2.0.0"; + + return properties; + } + + private Properties getRealProperties() { + Properties properties = new Properties(); + + properties.schemas.put("Catalog", List.of("Catalog.ttl", "Agent.ttl", "Kind.ttl", "PeriodOfTime.ttl")); + properties.schemas.put("Dataset", List.of("Dataset.ttl", "Agent.ttl", "Kind.ttl", "PeriodOfTime.ttl", "Attribution.ttl", "Identifier.ttl", "QualityCertificate.ttl", "Relationship.ttl")); + properties.schemas.put("Dataset Series", List.of("DatasetSeries.ttl", "Agent.ttl", "PeriodOfTime.ttl", "Kind.ttl")); + properties.schemas.put("Resource", List.of("Resource.ttl")); + properties.schemas.put("Distribution", List.of("Distribution.ttl", "PeriodOfTime.ttl", "Checksum.ttl")); + properties.schemas.put("Data Service", List.of("DataService.ttl", "Agent.ttl", "Kind.ttl", "Identifier.ttl")); + + properties.parentChild.put("Resource", List.of("Dataset", "Catalog", "Data Service")); + properties.resources.put("Sample Distribution", new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/adms#sample", "Distribution")); properties.resources.put("Dataset Series", @@ -51,10 +73,24 @@ private void getProperties() { properties.resources.put("Analytics Distribution", new Properties.ResourceProperties("Dataset", "http://healthdataportal.eu/ns/health#analytics", "Distribution")); - properties.schemasToPublish = List.of("Resource", "Catalog", "Dataset", "Dataset Series", "Distribution", "Data Service"); - properties.schemaVersion = "2.0.0"; + properties.schemasToPublish = List.of( + "Resource", + "Catalog", + "Dataset", + "Dataset Series", + "Distribution", + "Data Service" + ); - this.properties = properties; + properties.schemaVersion = "2.0.0"; + properties.inputDir = "https://raw.githubusercontent.com/Health-RI/health-ri-metadata/master/Formalisation(shacl)/Core/PiecesShape/"; + properties.templateDir = "C:\\Users\\PatrickDekker(Health\\templates\\"; + properties.outputRoot = "C:\\Users\\PatrickDekker(Health\\IdeaProjects\\health-ri-metadata\\Formalisation(shacl)\\Core\\"; + properties.piecesDir = "PiecesShape"; + properties.fairDataPointDir = "FairDataPointShape"; + properties.validationDir = "ValidationShape"; + + return properties; } List getResourceResponseList(String name1, String name2, String name3) { @@ -195,11 +231,12 @@ List getSchemaDataResponseList(String name1, String name2, S @Test void PropertyResourceNotFoundInFdpResourceInfoMap_WhenGettingResourceInfo_ResourceDataEmptyIdAndExistsFalse() { // Arrange + Properties properties = getTestProperties(); List fdpResourceResponseList = getResourceResponseList("resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); // Act & Assert - this.properties.resources.entrySet().forEach(propertyResource -> { + properties.resources.entrySet().forEach(propertyResource -> { ResourceTaskService.ResourceData resourceData = this.resourceTaskService.getResourceInfo(propertyResource.getKey(), fdpResourceInfoMap); @@ -212,11 +249,12 @@ void PropertyResourceNotFoundInFdpResourceInfoMap_WhenGettingResourceInfo_Resour @Test void PropertyResourceFoundInFdpResourceInfoMap_WhenGettingResourceInfo_ResourceDataIdIsFdpUuidIdAndExistsTrue() { // Arrange + Properties properties = getTestProperties(); List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); // Act & Assert - this.properties.resources.entrySet().forEach(propertyResource -> { + properties.resources.entrySet().forEach(propertyResource -> { ResourceTaskService.ResourceData resourceData = this.resourceTaskService.getResourceInfo(propertyResource.getKey(), fdpResourceInfoMap); @@ -230,13 +268,14 @@ void PropertyResourceFoundInFdpResourceInfoMap_WhenGettingResourceInfo_ResourceD @Test void PropertyResourceNotFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsEmptyId() { // Arrange + Properties properties = getTestProperties(); List fdpSchemaDataResponseList = getSchemaDataResponseList("resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); Map fdpSchemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); // Act & Assert - this.properties.resources.entrySet().forEach(propertyResource -> { + properties.resources.entrySet().forEach(propertyResource -> { // Act String resourceSchemaId = this.resourceTaskService.getSchemaUUID(propertyResource.getKey(), propertyResource.getValue().schema(), fdpSchemaInfoMap); @@ -248,15 +287,19 @@ void PropertyResourceNotFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsEmp @Test void PropertyResourceFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsSchemaIdFromFdpSchema() { // Arrange + Properties properties = getTestProperties(); List fdpSchemaDataResponseList = getSchemaDataResponseList("Catalog", "Dataset", "Resource"); Map fdpSchemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); // Act & Assert - this.properties.resources.entrySet().forEach(propertyResource -> { + properties.resources.entrySet().forEach(propertyResource -> { + String propertyResourceName = propertyResource.getKey(); + String propertyResourceSchema = propertyResource.getValue().schema(); + // Act - String resourceSchemaId = this.resourceTaskService.getSchemaUUID(propertyResource.getKey(), propertyResource.getValue().schema(), fdpSchemaInfoMap); + String resourceSchemaId = this.resourceTaskService.getSchemaUUID(propertyResourceName, propertyResourceSchema, fdpSchemaInfoMap); // Assert String expectedSchemaId = fdpSchemaInfoMap.get(propertyResource.getValue().schema()).uuid(); @@ -267,11 +310,12 @@ void PropertyResourceFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsSchema @Test void PropertyParentResourceNotFoundInFdpResourceInfoMap_WhenGettingParentResourceInfo_ReturnEmptyParentResourceData(){ // Arrange + Properties properties = getTestProperties(); List fdpResourceResponseList = getResourceResponseListWithParent("parent-resource-not-in-fdp", "resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); // Act & Assert - this.properties.resources.entrySet().forEach(propertyResource -> { + properties.resources.entrySet().forEach(propertyResource -> { ResourceTaskService.ParentResourceData resourceData = this.resourceTaskService.getParentResourceInfo(propertyResource, fdpResourceInfoMap); @@ -289,11 +333,12 @@ void PropertyParentResourceNotFoundInFdpResourceInfoMap_WhenGettingParentResourc @Test void PropertyParentResourceFoundInFdpResourceInfoMap_WhenGettingParentResourceInfo_ReturnParentResourceDataWithFilledChildInfo(){ // Arrange + Properties properties = getTestProperties(); List fdpResourceResponseList = getResourceResponseListWithParent("Dataset", "Sample Distribution", "Dataset Series", "Analytics Distribution"); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); // Act & Assert - this.properties.resources.entrySet().forEach(propertyResource -> { + properties.resources.entrySet().forEach(propertyResource -> { ResourceTaskService.ParentResourceData resourceData = this.resourceTaskService.getParentResourceInfo(propertyResource, fdpResourceInfoMap); @@ -314,41 +359,42 @@ void PropertyParentResourceFoundInFdpResourceInfoMap_WhenGettingParentResourceIn // createtasksgood // createtasksnotgood + // todo: @Test - void PropertyParentResourceNotFoundInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithEmptyChildInfo() { + void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTasksThatExist(){ // Arrange + Properties properties = getRealProperties(); List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); - + Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); + List fdpSchemaDataResponseList = getSchemaDataResponseList("Catalog", "Dataset", "Resource"); + Map fdpSchemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); + when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); + // Act - List result = resourceTaskService.createParentTasks(); + List result = resourceTaskService.createTasks(); // Assert - assertEquals(3, result.size()); - for(ResourceTask task : result){ - assertFalse(task.exists); + assertEquals(result.size(), fdpSchemaDataResponseList.size()); + for(ResourceTask resourceTask : result){ + // assertEquals(fdpResourceUuid, resourceData.resourceUUID()); + // assertTrue(resourceData.exists()); } } + // todo: @Test - void PropertyParentResourceFoundInFdpSchemaInfoMap_WhenCreatingParentTasks_ReturnResourceWithChildInfo(){ - // Arrange - List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); - List schemaDataResponseList = getSchemaDataResponseList("Resource", "Distribution", "Dataset"); + void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTasksThatDoNotExist(){} - when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); - when(fdpServiceMock.getAllSchemas()).thenReturn(schemaDataResponseList); + // todo: + @Test + void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingParentTasks_ReturnsTasksWithFilledChildDataAndExistsIsTrue(){} - // Act - List result = resourceTaskService.createTasks(); + // todo: + @Test + void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingParentTasks_ReturnsTasksWithEmptyChildDataAndExistsIsFalse(){} - // Assert - assertEquals(3, result.size()); - for(ResourceTask task : result){ - assertTrue(task.exists); - } - } @Test void TestResourceTaskService_RealScenario() { From fdd7b2f373d2fe08597aead41f2263a001d5f7a2 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Wed, 12 Nov 2025 11:54:11 +0100 Subject: [PATCH 35/51] feature: added test AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTasksThatExist --- .../services/ResourceTaskServiceTest.java | 380 +----------------- 1 file changed, 16 insertions(+), 364 deletions(-) diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index abddcae..1f1214a 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -29,6 +29,7 @@ class ResourceTaskServiceTest { @BeforeEach void setUp() { fdpServiceMock = mock(FdpService.class); + Properties properties = getRealProperties(); resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); } @@ -361,385 +362,36 @@ void PropertyParentResourceFoundInFdpResourceInfoMap_WhenGettingParentResourceIn // todo: @Test - void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTasksThatExist(){ + void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTasksThatExist() { // Arrange Properties properties = getRealProperties(); + resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); + List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); - Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); + Map resourceInfoMap = createResourceInfoMap(fdpResourceResponseList); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); - List fdpSchemaDataResponseList = getSchemaDataResponseList("Catalog", "Dataset", "Resource"); - Map fdpSchemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); + List fdpSchemaDataResponseList = getSchemaDataResponseList("Distribution", "Dataset Series", "Distribution"); + Map schemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); // Act List result = resourceTaskService.createTasks(); // Assert - assertEquals(result.size(), fdpSchemaDataResponseList.size()); - for(ResourceTask resourceTask : result){ - // assertEquals(fdpResourceUuid, resourceData.resourceUUID()); - // assertTrue(resourceData.exists()); + assertEquals(properties.resources.size(), result.size()); + for (ResourceTask task : result) { + Properties.ResourceProperties resourceProperty = properties.resources.get(task.resource); + String expectedSchemaUuid = schemaInfoMap.get(resourceProperty.schema()).uuid(); + String expectedFdpResourceId = resourceInfoMap.get(task.resource).uuid(); + + assertEquals(expectedSchemaUuid, task.shapeUUUID); + assertEquals(expectedFdpResourceId, task.UUID); + assertTrue(task.exists); } } - // todo: - @Test - void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTasksThatDoNotExist(){} - - // todo: - @Test - void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingParentTasks_ReturnsTasksWithFilledChildDataAndExistsIsTrue(){} - - // todo: - @Test - void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingParentTasks_ReturnsTasksWithEmptyChildDataAndExistsIsFalse(){} - - - @Test - void TestResourceTaskService_RealScenario() { - // Arrange - List fdpResourceResponseList = List.of( - new ResourceResponse( - "2f08228e-1789-40f8-84cd-28e3288c3604", - "Dataset", - null, - null, - null, - null, - null - ), - new ResourceResponse( - "02c649de-c579-43bb-b470-306abdc808c7", - "Distribution", - null, - null, - null, - null, - null - ), - new ResourceResponse( - "77aaad6a-0136-4c6e-88b9-07ffccd0ee4c", - "FAIR Data Point", - null, - null, - null, - null, - null - ), - new ResourceResponse( - "fc089ccc-c06d-4090-bf46-74b9192e5d04", - "Dataset Series", - null, - null, - null, - null, - null - ), - new ResourceResponse( - "2da98613-5673-4741-b131-a1410953c3f0", - "Analytics Distribution", - null, - null, - null, - null, - null - ), - new ResourceResponse( - "b117e67a-937c-4115-be6d-d79ef5ddadf4", - "Sample Distribution", - null, - null, - null, - null, - null - ) - ); - - List schemaDataResponseList = List.of( - new SchemaDataResponse( - "6f7a5a76-6185-4bd0-9fe9-62ecc90c9bad", - "Metadata Service", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ), - new SchemaDataResponse( - "a92958ab-a414-47e6-8e17-68ba96ba3a2b", - "FAIR Data Point", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ), - new SchemaDataResponse( - "6a668323-3936-4b53-8380-a4fd2ed082ee", - "Resource", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ), - new SchemaDataResponse( - "866d7fb8-5982-4215-9c7c-18d0ed1bd5f3", - "Dataset", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ), - new SchemaDataResponse( - "0bc517a8-79e5-427a-b0a5-100aa32d58ee", - "Dataset Series", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ), - new SchemaDataResponse( - "ebacbf83-cd4f-4113-8738-d73c0735b0ab", - "Distribution", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ), - new SchemaDataResponse( - "89d94c1b-f6ff-4545-ba9b-120b2d1921d0", - "Data Service", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ), - new SchemaDataResponse( - "2aa7ba63-d27a-4c0e-bfa6-3a4e250f4660", - "Catalog", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ), - new SchemaDataResponse( - "ebacbf83-cd4f-4113-8738-d73c0735b0ab", - "Distribution", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - new ArrayList<>(List.of(new Version(1, 0, 0).toString())), - null, - null - ), - new SchemaDataResponse( - "ebacbf83-cd4f-4113-8738-d73c0735b0ab", - "Distribution", - new SchemaDataResponse.Latest( - null, - new Version(1, 0, 0).toString(), - null, - null, - null, - false, - false, - true, - null, - null, - null, - null, - null, - null, - null, - null, - null - ), - null, - null, - null, - null - ) - ); - - when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); - when(fdpServiceMock.getAllSchemas()).thenReturn(schemaDataResponseList); - // Act - List result = resourceTaskService.createTasks(); - // Assert - assertEquals(3, result.size()); - for(ResourceTask task : result){ - assertEquals(true, task.exists); - } - } } \ No newline at end of file From 251c78cb28d865545241ef38028d21ed0208b249 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Wed, 12 Nov 2025 13:04:41 +0100 Subject: [PATCH 36/51] fix: fixed all tests --- .../services/ResourceTaskServiceTest.java | 85 +++++++++++++++++-- 1 file changed, 80 insertions(+), 5 deletions(-) diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index 1f1214a..99c66f3 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -368,7 +368,7 @@ void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTask resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); - Map resourceInfoMap = createResourceInfoMap(fdpResourceResponseList); + Map fdpResourceMap = createResourceInfoMap(fdpResourceResponseList); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); List fdpSchemaDataResponseList = getSchemaDataResponseList("Distribution", "Dataset Series", "Distribution"); @@ -382,16 +382,91 @@ void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTask assertEquals(properties.resources.size(), result.size()); for (ResourceTask task : result) { Properties.ResourceProperties resourceProperty = properties.resources.get(task.resource); - String expectedSchemaUuid = schemaInfoMap.get(resourceProperty.schema()).uuid(); - String expectedFdpResourceId = resourceInfoMap.get(task.resource).uuid(); + String expectedResourceName = fdpResourceMap.get(task.resource).name(); + String expectedResourceId = fdpResourceMap.get(task.resource).uuid(); + String expectedResourceSchemaUuid = schemaInfoMap.get(resourceProperty.schema()).uuid(); + + assertEquals(expectedResourceName, task.resource); + assertEquals(expectedResourceId, task.UUID); + assertEquals(expectedResourceSchemaUuid, task.shapeUUUID); + assertTrue(task.exists); + } + } + + @Test + void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTasksThatDoNotExist() { + // Arrange + Properties properties = getRealProperties(); + resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); + + List fdpResourceResponseList = getResourceResponseList("not-in-fdp-1", "not-in-fdp-2", "not-in-fdp-3"); + Map fdpResourceMap = createResourceInfoMap(fdpResourceResponseList); + when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); + + List fdpSchemaDataResponseList = getSchemaDataResponseList("Distribution", "Dataset Series", "Distribution"); + Map schemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); + when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); + + // Act + List result = resourceTaskService.createTasks(); + + // Assert + assertEquals(properties.resources.size(), result.size()); + for (ResourceTask task : result) { + assertEquals("", task.UUID); + assertFalse(task.exists); + } + } + + @Test + void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingParentTasks_ReturnsTasksWithFilledChildDataAndExistsIsTrue() { + // Arrange + Properties properties = getRealProperties(); + resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); + + List fdpResourceResponseList = getResourceResponseListWithParent("Dataset", "Sample Distribution", "Dataset Series", "Analytics Distribution"); + Map resourceInfoMap = createResourceInfoMap(fdpResourceResponseList); + when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); + + // Act + List result = resourceTaskService.createParentTasks(); + + assertEquals(properties.resources.size(), result.size()); + for (ResourceTask task : result) { + Properties.ResourceProperties resourceProperty = properties.resources.get(task.childName); + String expectedParentResourceName = resourceProperty.parentResource(); + String expectedUuid = resourceInfoMap.get(resourceProperty.parentResource()).uuid(); + String expectedChildUuid = resourceInfoMap.get(task.childName).uuid(); + String expectedChildIri = resourceProperty.parentRelationIri(); - assertEquals(expectedSchemaUuid, task.shapeUUUID); - assertEquals(expectedFdpResourceId, task.UUID); + // Assert + assertEquals(expectedParentResourceName, task.resource); + assertEquals(expectedUuid, task.UUID); + assertEquals(expectedChildUuid, task.childUUuid); + assertEquals(expectedChildIri, task.childRelationIri); assertTrue(task.exists); } } + @Test + void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingParentTasks_ReturnsTasksWithEmptyChildDataAndExistsIsFalse() { + // Arrange + Properties properties = getRealProperties(); + resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); + List fdpResourceResponseList = getResourceResponseListWithParent("not-in-fdp-parent", "not-in-fdp-1", "not-in-fdp-2", "not-in-fdp-3"); + when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); + // Act + List result = resourceTaskService.createParentTasks(); + + // Assert + assertEquals(properties.resources.size(), result.size()); + for (ResourceTask task : result) { + assertNull(task.childUUuid); + assertNull(task.childRelationIri); + assertFalse(task.exists); + } + } } \ No newline at end of file From deef7f79103c32ca0ff3f92fabf9efba93487971 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Wed, 12 Nov 2025 13:42:46 +0100 Subject: [PATCH 37/51] fix: moved properties back to constructor --- .../services/ResourceTaskServiceTest.java | 71 +++++-------------- .../services/ShapeTaskServiceTest.java | 3 +- 2 files changed, 18 insertions(+), 56 deletions(-) diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index 99c66f3..6c4954b 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -29,33 +29,11 @@ class ResourceTaskServiceTest { @BeforeEach void setUp() { fdpServiceMock = mock(FdpService.class); - Properties properties = getRealProperties(); + Properties properties = getProperties(); resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); } - private Properties getTestProperties() { - Properties properties = new Properties(); - - properties.schemas.put("Catalog", List.of("Catalog.ttl", "Agent.ttl", "Kind.ttl")); - properties.schemas.put("Dataset", List.of("Dataset.ttl", "Agent.ttl", "Kind.ttl","PeriodOfTime.ttl","Attribution.ttl","Identifier.ttl","QualityCertificate.ttl","Relationship.ttl")); - properties.schemas.put("Resource", List.of("Resource.ttl")); - - properties.parentChild.put("Resource", List.of("Dataset", "Catalog", "Data Service")); - - properties.resources.put("Sample Distribution", - new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/adms#sample", "Catalog")); - properties.resources.put("Dataset Series", - new Properties.ResourceProperties("Dataset", "http://www.w3.org/ns/dcat#inSeries", "Dataset")); - properties.resources.put("Analytics Distribution", - new Properties.ResourceProperties("Dataset", "http://healthdataportal.eu/ns/health#analytics", "Resource")); - - properties.schemasToPublish = List.of("Resource", "Catalog", "Dataset", "Dataset Series", "Distribution", "Data Service"); - properties.schemaVersion = "2.0.0"; - - return properties; - } - - private Properties getRealProperties() { + private Properties getProperties() { Properties properties = new Properties(); properties.schemas.put("Catalog", List.of("Catalog.ttl", "Agent.ttl", "Kind.ttl", "PeriodOfTime.ttl")); @@ -232,12 +210,11 @@ List getSchemaDataResponseList(String name1, String name2, S @Test void PropertyResourceNotFoundInFdpResourceInfoMap_WhenGettingResourceInfo_ResourceDataEmptyIdAndExistsFalse() { // Arrange - Properties properties = getTestProperties(); List fdpResourceResponseList = getResourceResponseList("resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); // Act & Assert - properties.resources.entrySet().forEach(propertyResource -> { + this.resourceTaskService.properties.resources.entrySet().forEach(propertyResource -> { ResourceTaskService.ResourceData resourceData = this.resourceTaskService.getResourceInfo(propertyResource.getKey(), fdpResourceInfoMap); @@ -250,12 +227,11 @@ void PropertyResourceNotFoundInFdpResourceInfoMap_WhenGettingResourceInfo_Resour @Test void PropertyResourceFoundInFdpResourceInfoMap_WhenGettingResourceInfo_ResourceDataIdIsFdpUuidIdAndExistsTrue() { // Arrange - Properties properties = getTestProperties(); List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); // Act & Assert - properties.resources.entrySet().forEach(propertyResource -> { + this.resourceTaskService.properties.resources.entrySet().forEach(propertyResource -> { ResourceTaskService.ResourceData resourceData = this.resourceTaskService.getResourceInfo(propertyResource.getKey(), fdpResourceInfoMap); @@ -269,14 +245,13 @@ void PropertyResourceFoundInFdpResourceInfoMap_WhenGettingResourceInfo_ResourceD @Test void PropertyResourceNotFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsEmptyId() { // Arrange - Properties properties = getTestProperties(); List fdpSchemaDataResponseList = getSchemaDataResponseList("resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); Map fdpSchemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); // Act & Assert - properties.resources.entrySet().forEach(propertyResource -> { + this.resourceTaskService.properties.resources.entrySet().forEach(propertyResource -> { // Act String resourceSchemaId = this.resourceTaskService.getSchemaUUID(propertyResource.getKey(), propertyResource.getValue().schema(), fdpSchemaInfoMap); @@ -288,14 +263,13 @@ void PropertyResourceNotFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsEmp @Test void PropertyResourceFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsSchemaIdFromFdpSchema() { // Arrange - Properties properties = getTestProperties(); - List fdpSchemaDataResponseList = getSchemaDataResponseList("Catalog", "Dataset", "Resource"); + List fdpSchemaDataResponseList = getSchemaDataResponseList("Distribution", "Dataset Series", "Distribution"); Map fdpSchemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); // Act & Assert - properties.resources.entrySet().forEach(propertyResource -> { + this.resourceTaskService.properties.resources.entrySet().forEach(propertyResource -> { String propertyResourceName = propertyResource.getKey(); String propertyResourceSchema = propertyResource.getValue().schema(); @@ -311,12 +285,11 @@ void PropertyResourceFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsSchema @Test void PropertyParentResourceNotFoundInFdpResourceInfoMap_WhenGettingParentResourceInfo_ReturnEmptyParentResourceData(){ // Arrange - Properties properties = getTestProperties(); List fdpResourceResponseList = getResourceResponseListWithParent("parent-resource-not-in-fdp", "resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); // Act & Assert - properties.resources.entrySet().forEach(propertyResource -> { + this.resourceTaskService.properties.resources.entrySet().forEach(propertyResource -> { ResourceTaskService.ParentResourceData resourceData = this.resourceTaskService.getParentResourceInfo(propertyResource, fdpResourceInfoMap); @@ -334,12 +307,12 @@ void PropertyParentResourceNotFoundInFdpResourceInfoMap_WhenGettingParentResourc @Test void PropertyParentResourceFoundInFdpResourceInfoMap_WhenGettingParentResourceInfo_ReturnParentResourceDataWithFilledChildInfo(){ // Arrange - Properties properties = getTestProperties(); + List fdpResourceResponseList = getResourceResponseListWithParent("Dataset", "Sample Distribution", "Dataset Series", "Analytics Distribution"); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); // Act & Assert - properties.resources.entrySet().forEach(propertyResource -> { + this.resourceTaskService.properties.resources.entrySet().forEach(propertyResource -> { ResourceTaskService.ParentResourceData resourceData = this.resourceTaskService.getParentResourceInfo(propertyResource, fdpResourceInfoMap); @@ -364,8 +337,7 @@ void PropertyParentResourceFoundInFdpResourceInfoMap_WhenGettingParentResourceIn @Test void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTasksThatExist() { // Arrange - Properties properties = getRealProperties(); - resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); + List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); Map fdpResourceMap = createResourceInfoMap(fdpResourceResponseList); @@ -379,9 +351,9 @@ void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTask List result = resourceTaskService.createTasks(); // Assert - assertEquals(properties.resources.size(), result.size()); + assertEquals(this.resourceTaskService.properties.resources.size(), result.size()); for (ResourceTask task : result) { - Properties.ResourceProperties resourceProperty = properties.resources.get(task.resource); + Properties.ResourceProperties resourceProperty = this.resourceTaskService.properties.resources.get(task.resource); String expectedResourceName = fdpResourceMap.get(task.resource).name(); String expectedResourceId = fdpResourceMap.get(task.resource).uuid(); String expectedResourceSchemaUuid = schemaInfoMap.get(resourceProperty.schema()).uuid(); @@ -396,9 +368,6 @@ void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTask @Test void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTasksThatDoNotExist() { // Arrange - Properties properties = getRealProperties(); - resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); - List fdpResourceResponseList = getResourceResponseList("not-in-fdp-1", "not-in-fdp-2", "not-in-fdp-3"); Map fdpResourceMap = createResourceInfoMap(fdpResourceResponseList); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); @@ -411,7 +380,7 @@ void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsT List result = resourceTaskService.createTasks(); // Assert - assertEquals(properties.resources.size(), result.size()); + assertEquals(this.resourceTaskService.properties.resources.size(), result.size()); for (ResourceTask task : result) { assertEquals("", task.UUID); assertFalse(task.exists); @@ -421,9 +390,6 @@ void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsT @Test void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingParentTasks_ReturnsTasksWithFilledChildDataAndExistsIsTrue() { // Arrange - Properties properties = getRealProperties(); - resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); - List fdpResourceResponseList = getResourceResponseListWithParent("Dataset", "Sample Distribution", "Dataset Series", "Analytics Distribution"); Map resourceInfoMap = createResourceInfoMap(fdpResourceResponseList); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); @@ -431,9 +397,9 @@ void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingParentTasks_Retur // Act List result = resourceTaskService.createParentTasks(); - assertEquals(properties.resources.size(), result.size()); + assertEquals(this.resourceTaskService.properties.resources.size(), result.size()); for (ResourceTask task : result) { - Properties.ResourceProperties resourceProperty = properties.resources.get(task.childName); + Properties.ResourceProperties resourceProperty = this.resourceTaskService.properties.resources.get(task.childName); String expectedParentResourceName = resourceProperty.parentResource(); String expectedUuid = resourceInfoMap.get(resourceProperty.parentResource()).uuid(); String expectedChildUuid = resourceInfoMap.get(task.childName).uuid(); @@ -451,9 +417,6 @@ void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingParentTasks_Retur @Test void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingParentTasks_ReturnsTasksWithEmptyChildDataAndExistsIsFalse() { // Arrange - Properties properties = getRealProperties(); - resourceTaskService = new ResourceTaskService(fdpServiceMock, properties); - List fdpResourceResponseList = getResourceResponseListWithParent("not-in-fdp-parent", "not-in-fdp-1", "not-in-fdp-2", "not-in-fdp-3"); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); @@ -461,7 +424,7 @@ void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingParentTasks_Re List result = resourceTaskService.createParentTasks(); // Assert - assertEquals(properties.resources.size(), result.size()); + assertEquals(this.resourceTaskService.properties.resources.size(), result.size()); for (ResourceTask task : result) { assertNull(task.childUUuid); assertNull(task.childRelationIri); diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java index 88ad0d4..f1a51d3 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java @@ -8,7 +8,6 @@ import nl.healthri.fdp.uploadschema.utils.Properties; import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.model.impl.LinkedHashModel; -import org.eclipse.rdf4j.model.util.Models; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.Mock; @@ -275,4 +274,4 @@ void ChangesFound_WhenComparingPropertiesFileWithMatchingFdpShapeFile_ReturnsNew // Assert assertEquals(ShapeStatus.UPDATE, tasks.getFirst().status()); } -} +} \ No newline at end of file From 75d33e995c746cd5049437f97ec5f1dac857fb36 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Wed, 26 Nov 2025 10:53:47 +0100 Subject: [PATCH 38/51] feature: added update settings --- FdpSettings.json | 64 +++++++ .../fdp/uploadschema/SchemaTools.java | 14 +- .../{utils => config/fdp}/Properties.java | 2 +- .../fdp/uploadschema/config/fdp/Settings.java | 164 ++++++++++++++++++ .../Resource/ResourceRequest.java | 2 +- .../Resource/ResourceResponse.java | 2 +- .../Resource/UpdateResourceResponse.java | 4 +- .../Schema/ReleaseSchemaRequest.java | 2 +- .../Schema/SchemaDataResponse.java | 2 +- .../Schema/UpdateSchemaRequest.java | 2 +- .../Schema/UpdateSchemaResponse.java | 2 +- .../dto/Settings/SettingsResponse.java | 52 ++++++ .../dto/{request => }/auth/LoginRequest.java | 2 +- .../{response => }/auth/LoginResponse.java | 2 +- .../uploadschema/integrations/FdpClient.java | 76 +++++++- .../integrations/FdpClientInterface.java | 19 +- .../fdp/uploadschema/services/FdpService.java | 23 ++- .../services/FdpServiceInterface.java | 7 +- .../services/ResourceTaskService.java | 7 +- .../services/SchemaToolService.java | 2 +- .../services/ShapeTaskService.java | 4 +- .../fdp/uploadschema/utils/ResourceInfo.java | 2 +- .../fdp/uploadschema/utils/SchemaInfo.java | 2 +- .../services/ResourceTaskServiceTest.java | 6 +- .../services/ShapeTaskServiceTest.java | 4 +- .../utils/PropertiesYamlTest.java | 1 + 26 files changed, 419 insertions(+), 50 deletions(-) create mode 100644 FdpSettings.json rename src/main/java/nl/healthri/fdp/uploadschema/{utils => config/fdp}/Properties.java (99%) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java rename src/main/java/nl/healthri/fdp/uploadschema/dto/{request => }/Resource/ResourceRequest.java (89%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/{response => }/Resource/ResourceResponse.java (93%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/{response => }/Resource/UpdateResourceResponse.java (82%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/{request => }/Schema/ReleaseSchemaRequest.java (91%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/{response => }/Schema/SchemaDataResponse.java (93%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/{request => }/Schema/UpdateSchemaRequest.java (83%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/{response => }/Schema/UpdateSchemaResponse.java (85%) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/dto/Settings/SettingsResponse.java rename src/main/java/nl/healthri/fdp/uploadschema/dto/{request => }/auth/LoginRequest.java (62%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/{response => }/auth/LoginResponse.java (68%) diff --git a/FdpSettings.json b/FdpSettings.json new file mode 100644 index 0000000..447cd64 --- /dev/null +++ b/FdpSettings.json @@ -0,0 +1,64 @@ +{ + "clientUrl": "http://localhost", + "persistentUrl": "http://localhost:8080", + "appTitle": null, + "appSubtitle": null, + "appTitleFromConfig": "FAIR Data Point", + "appSubtitleFromConfig": "Metadata for machines", + "metadataMetrics": [ + { + "metricUri": "https://purl.org/fair-metrics/FM_F1A", + "resourceUri": "https://www.ietf.org/rfc/rfc3986.txt" + }, + { + "metricUri": "https://purl.org/fair-metrics/FM_A1.1", + "resourceUri": "https://www.wikidata.org/wiki/Q8777" + } + ], + "ping": { + "enabled": true, + "endpoints": [], + "endpointsFromConfig": [ + "https://home.fairdatapoint.org" + ], + "interval": "PT168H" + }, + "repository": { + "type": "InMemory" + }, + "search": { + "filters": [] + }, + "forms": { + "autocomplete": { + "searchNamespace": true, + "sources": [ + { + "rdfType": "http://purl.org/dc/terms/LinguisticSystem", + "sparqlEndpoint": "https://sparql-test.healthdata.nl/repositories/controlled-vocabularies", + "sparqlQuery": "PREFIX skos: \nSELECT ?entity ?entityLabel WHERE {\n ?entity skos:prefLabel ?entityLabel\n FILTER ( lang(?entityLabel) = \"en\")\n}\n" + }, + { + "rdfType": "http://purl.org/dc/terms/Frequency", + "sparqlEndpoint": "https://sparql-test.healthdata.nl/repositories/controlled-vocabularies", + "sparqlQuery": "PREFIX skos: \nSELECT ?entity ?entityLabel WHERE {\n GRAPH {\n ?entity skos:prefLabel ?entityLabel\n FILTER ( lang(?entityLabel) = \"en\")\n }\n}" + }, + { + "rdfType": "http://purl.org/dc/terms/MediaTypeOrExtent", + "sparqlEndpoint": "https://sparql-test.healthdata.nl/repositories/controlled-vocabularies", + "sparqlQuery": "PREFIX skos: \nSELECT ?entity ?entityLabel WHERE {\n GRAPH {\n ?entity skos:prefLabel ?entityLabel\n FILTER ( lang(?entityLabel) = \"en\")\n }\n}" + }, + { + "rdfType": "http://purl.org/dc/terms/Concept", + "sparqlEndpoint": "https://sparql-test.healthdata.nl/repositories/controlled-vocabularies", + "sparqlQuery": "PREFIX skos: \nSELECT ?entity ?entityLabel WHERE {\n GRAPH {\n ?entity skos:prefLabel ?entityLabel\n FILTER ( lang(?entityLabel) = \"en\")\n }\n}" + }, + { + "rdfType": "http://purl.org/dc/terms/Test", + "sparqlEndpoint": "https://sparql-test.healthdata.nl/repositories/test", + "sparqlQuery": "PREFIX skos: \nSELECT ?entity ?entityLabel WHERE {\n GRAPH {\n ?entity skos:prefLabel ?entityLabel\n FILTER ( lang(?entityLabel) = \"en\")\n }\n}" + } + ] + } + } +} \ No newline at end of file diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index d7c2613..4d4c416 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -1,13 +1,14 @@ package nl.healthri.fdp.uploadschema; import com.fasterxml.jackson.databind.ObjectMapper; +import nl.healthri.fdp.uploadschema.config.fdp.Settings; import nl.healthri.fdp.uploadschema.integrations.FdpClient; import nl.healthri.fdp.uploadschema.services.FdpService; import nl.healthri.fdp.uploadschema.services.ResourceTaskService; import nl.healthri.fdp.uploadschema.services.SchemaToolService; import nl.healthri.fdp.uploadschema.services.ShapeTaskService; import nl.healthri.fdp.uploadschema.utils.FileHandler; -import nl.healthri.fdp.uploadschema.utils.Properties; +import nl.healthri.fdp.uploadschema.config.fdp.Properties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import picocli.CommandLine; @@ -25,6 +26,9 @@ public class SchemaTools implements Runnable { private static final Logger logger = LoggerFactory.getLogger(SchemaTools.class); + @CommandLine.Option(names = {"-s", "--settings"}, defaultValue = "./FdpSettings.json", description = "location of the FdpSettings.json file (default: ${DEFAULT-VALUE})") + File settingsFile; + @CommandLine.Option(names = {"-i", "--input"}, defaultValue = "./Properties.yaml", description = "location of the Property.yaml file (default: ${DEFAULT-VALUE})") File propertyFile; @@ -59,14 +63,20 @@ public void run() { final ObjectMapper objectMapper = new ObjectMapper(); final FdpClient fdpClient = new FdpClient(client, this.hostname, objectMapper); final FdpService fdpService = new FdpService(fdpClient); + final Properties properties = Properties.load(propertyFile); - final FileHandler fileHandler = new FileHandler(); + final ResourceTaskService resourceTaskService = new ResourceTaskService(fdpService, properties); + + final FileHandler fileHandler = new FileHandler(); final ShapeTaskService shapeTaskService = new ShapeTaskService(fdpService, fileHandler, properties); final SchemaToolService schemaToolService = new SchemaToolService(fdpService, resourceTaskService, shapeTaskService, properties, fileHandler); fdpService.authenticate(this.username, this.password); + final Settings newFdpSettings = Settings.GetSettings(settingsFile); + fdpService.updateSettings(newFdpSettings); + switch (command) { case TEMPLATE -> { schemaToolService.convertTemplatesToShaclShapes(); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java b/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Properties.java similarity index 99% rename from src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java rename to src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Properties.java index cb0bed0..3d9eb31 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/Properties.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Properties.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.utils; +package nl.healthri.fdp.uploadschema.config.fdp; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.core.exc.StreamReadException; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java b/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java new file mode 100644 index 0000000..ce542b9 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java @@ -0,0 +1,164 @@ +package nl.healthri.fdp.uploadschema.config.fdp; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.exc.StreamReadException; +import com.fasterxml.jackson.databind.DatabindException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import nl.healthri.fdp.uploadschema.dto.Settings.SettingsResponse; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; + +public class Settings { + private static Settings settings; + + public String clientUrl; + public String persistentUrl; + public String appTitle; + public String appSubtitle; + public String appTitleFromConfig; + public String appSubtitleFromConfig; + public List metadataMetrics; + public Ping ping; + public Repository repository; + public Search search; + public Forms forms; + + public Settings() {} + + public static class MetadataMetric { + public String metricUri; + public String resourceUri; + + } + + public static class Ping { + public boolean enabled; + public List endpoints; + public List endpointsFromConfig; + public String interval; + + } + + public static class Repository { + public String type; + + } + + public static class Search { + public List filters; + + } + + public static class Forms { + public Autocomplete autocomplete; + + + public static class Autocomplete { + public boolean searchNamespace; + public List sources; + + + public static class Source { + public String rdfType; + public String sparqlEndpoint; + public String sparqlQuery; + + } + } + } + + // Always returns the existing settings if already initialized. + public static Settings GetSettings(File file) throws IOException { + if(settings == null){ + if (!file.exists() || !file.isFile()) { + throw new FileNotFoundException("Settings file not found: " + file.getAbsolutePath()); + } + ObjectMapper mapper = new ObjectMapper(); + settings = mapper.readValue(file, Settings.class); + + } + + return settings; + } + + + // Merges all data from fdpSettings into Settings instance only adding missing form sources from Settings instance + public Settings Merge(SettingsResponse fdpSettings){ + Settings mergedSettings = settings; + + mergedSettings.clientUrl = fdpSettings.clientUrl(); + mergedSettings.persistentUrl = fdpSettings.persistentUrl(); + mergedSettings.appTitle = fdpSettings.appTitle(); + mergedSettings.appSubtitle = fdpSettings.appSubtitle(); + mergedSettings.appTitleFromConfig = fdpSettings.appTitleFromConfig(); + mergedSettings.appSubtitleFromConfig = fdpSettings.appSubtitleFromConfig(); + mergedSettings.metadataMetrics = fdpSettings.metadataMetrics().stream() + .map(m -> { + MetadataMetric mm = new MetadataMetric(); + mm.metricUri = m.metricUri(); + mm.resourceUri = m.resourceUri(); + return mm; + }).toList(); + + if (mergedSettings.ping == null) mergedSettings.ping = new Ping(); + mergedSettings.ping.enabled = fdpSettings.ping().enabled(); + mergedSettings.ping.endpoints = fdpSettings.ping().endpoints(); + mergedSettings.ping.endpointsFromConfig = fdpSettings.ping().endpointsFromConfig(); + mergedSettings.ping.interval = fdpSettings.ping().interval(); + + if (mergedSettings.repository == null) mergedSettings.repository = new Repository(); + this.repository.type = fdpSettings.repository().type(); + + if (mergedSettings.search == null) mergedSettings.search = new Search(); + mergedSettings.search.filters = fdpSettings.search().filters(); + + if (mergedSettings.forms == null) mergedSettings.forms = new Forms(); + if (mergedSettings.forms.autocomplete == null) mergedSettings.forms.autocomplete = new Forms.Autocomplete(); + + mergedSettings.forms.autocomplete.searchNamespace = + fdpSettings.forms().autocomplete().searchNamespace(); + + List mergedSources = + new java.util.ArrayList<>(); + + List existingSources = + mergedSettings.forms.autocomplete.sources; + + List incomingSources = + fdpSettings.forms().autocomplete().sources(); + + // todo: allow multiple rdf types? + java.util.Map incomingByRdfType = + incomingSources.stream().collect( + java.util.stream.Collectors.toMap( + SettingsResponse.Forms.Autocomplete.Source::rdfType, + s -> { + Forms.Autocomplete.Source src = new Forms.Autocomplete.Source(); + src.rdfType = s.rdfType(); + src.sparqlEndpoint = s.sparqlEndpoint(); + src.sparqlQuery = s.sparqlQuery(); + return src; + } + )); + + if (existingSources != null) { + for (Forms.Autocomplete.Source existing : existingSources) { + if (incomingByRdfType.containsKey(existing.rdfType)) { + mergedSources.add(incomingByRdfType.get(existing.rdfType)); + incomingByRdfType.remove(existing.rdfType); + } else { + mergedSources.add(existing); + } + } + } + + mergedSources.addAll(incomingByRdfType.values()); + mergedSettings.forms.autocomplete.sources = mergedSources; + + return this; + } +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Resource/ResourceRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/ResourceRequest.java similarity index 89% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/request/Resource/ResourceRequest.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/ResourceRequest.java index 721a10c..cbe29cd 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Resource/ResourceRequest.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/ResourceRequest.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.request.Resource; +package nl.healthri.fdp.uploadschema.dto.Resource; import java.util.ArrayList; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/ResourceResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/ResourceResponse.java similarity index 93% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/ResourceResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/ResourceResponse.java index 4c5ed7c..fa90b9b 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/ResourceResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/ResourceResponse.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.response.Resource; +package nl.healthri.fdp.uploadschema.dto.Resource; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/UpdateResourceResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/UpdateResourceResponse.java similarity index 82% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/UpdateResourceResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/UpdateResourceResponse.java index fdffc1b..78d827a 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Resource/UpdateResourceResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/UpdateResourceResponse.java @@ -1,6 +1,6 @@ -package nl.healthri.fdp.uploadschema.dto.response.Resource; +package nl.healthri.fdp.uploadschema.dto.Resource; -import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; +import nl.healthri.fdp.uploadschema.dto.Resource.ResourceRequest; import java.util.ArrayList; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/ReleaseSchemaRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/ReleaseSchemaRequest.java similarity index 91% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/ReleaseSchemaRequest.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/ReleaseSchemaRequest.java index 492d1a0..ffa3cb9 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/ReleaseSchemaRequest.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/ReleaseSchemaRequest.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.request.Schema; +package nl.healthri.fdp.uploadschema.dto.Schema; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Schema/SchemaDataResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/SchemaDataResponse.java similarity index 93% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/response/Schema/SchemaDataResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/SchemaDataResponse.java index b0f3136..9f6164a 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Schema/SchemaDataResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/SchemaDataResponse.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.response.Schema; +package nl.healthri.fdp.uploadschema.dto.Schema; import java.util.ArrayList; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/UpdateSchemaRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/UpdateSchemaRequest.java similarity index 83% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/UpdateSchemaRequest.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/UpdateSchemaRequest.java index e9ddf83..c9d8fab 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/Schema/UpdateSchemaRequest.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/UpdateSchemaRequest.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.request.Schema; +package nl.healthri.fdp.uploadschema.dto.Schema; import java.util.Set; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Schema/UpdateSchemaResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/UpdateSchemaResponse.java similarity index 85% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/response/Schema/UpdateSchemaResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/UpdateSchemaResponse.java index b4630fa..3be9a63 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/Schema/UpdateSchemaResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/UpdateSchemaResponse.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.response.Schema; +package nl.healthri.fdp.uploadschema.dto.Schema; import java.util.HashSet; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/Settings/SettingsResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/Settings/SettingsResponse.java new file mode 100644 index 0000000..62abcd2 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/Settings/SettingsResponse.java @@ -0,0 +1,52 @@ +package nl.healthri.fdp.uploadschema.dto.Settings; + +import java.util.List; + +public record SettingsResponse( + String clientUrl, + String persistentUrl, + String appTitle, + String appSubtitle, + String appTitleFromConfig, + String appSubtitleFromConfig, + List metadataMetrics, + Ping ping, + Repository repository, + Search search, + Forms forms +) { + public record MetadataMetric( + String metricUri, + String resourceUri + ) {} + + public record Ping( + boolean enabled, + List endpoints, + List endpointsFromConfig, + String interval + ) {} + + public record Repository( + String type + ) {} + + public record Search( + List filters + ) {} + + public record Forms( + Autocomplete autocomplete + ) { + public record Autocomplete( + boolean searchNamespace, + List sources + ) { + public record Source( + String rdfType, + String sparqlEndpoint, + String sparqlQuery + ) {} + } + } +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/auth/LoginRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginRequest.java similarity index 62% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/request/auth/LoginRequest.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginRequest.java index 562da9b..e479182 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/request/auth/LoginRequest.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginRequest.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.request.auth; +package nl.healthri.fdp.uploadschema.dto.auth; public record LoginRequest(String email, String password) { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/auth/LoginResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginResponse.java similarity index 68% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/response/auth/LoginResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginResponse.java index 58c83b1..294f8f0 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/response/auth/LoginResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginResponse.java @@ -1,4 +1,4 @@ -package nl.healthri.fdp.uploadschema.dto.response.auth; +package nl.healthri.fdp.uploadschema.dto.auth; public record LoginResponse(String token) { public String asHeaderString() { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java index b69ae72..8554479 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java @@ -2,15 +2,17 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import nl.healthri.fdp.uploadschema.config.fdp.Settings; import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; -import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; -import nl.healthri.fdp.uploadschema.dto.request.Schema.ReleaseSchemaRequest; -import nl.healthri.fdp.uploadschema.dto.request.Schema.UpdateSchemaRequest; -import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; -import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; +import nl.healthri.fdp.uploadschema.dto.Resource.ResourceRequest; +import nl.healthri.fdp.uploadschema.dto.Schema.ReleaseSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.Schema.UpdateSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.Settings.SettingsResponse; +import nl.healthri.fdp.uploadschema.dto.auth.LoginRequest; +import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.auth.LoginResponse; import nl.healthri.fdp.uploadschema.utils.HttpRequestUtils; import org.slf4j.Logger; @@ -334,4 +336,64 @@ public void updateResource(ResourceTask task, ResourceResponse resourceResponse) throw new RuntimeException(e); } } + + + public SettingsResponse getSettings() { + logger.info("getting settings from FDP"); + + try { + isAuthenticated(); + + URI uri = new URI(this.hostname + "/settings"); + + HttpRequest request = HttpRequest.newBuilder() + .GET() + .uri(uri) + .header("accept", "application/json") + .header("Content-Type", "application/json") + .header("Authorization", this.authToken) + .build(); + + // Sends request + HttpResponse response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Handle each response based on Fair Data Point (FDP) Swagger documentation. + HttpRequestUtils.handleResponseStatus(response); + + // Maps response body to object + return objectMapper.readValue(response.body(), SettingsResponse.class); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public void updateSettings(Settings settings) { + logger.info("updating settings in FDP"); + + try { + isAuthenticated(); + + URI uri = new URI(this.hostname + "/settings"); + + HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString( + this.objectMapper.writeValueAsString(settings) + ); + + HttpRequest request = HttpRequest.newBuilder() + .PUT(body) + .uri(uri) + .header("accept", "application/json") + .header("Content-Type", "application/json") + .header("Authorization", this.authToken) + .build(); + + // Sends request + HttpResponse response = this.client.send(request, HttpResponse.BodyHandlers.ofString()); + + // Handle each response based on Fair Data Point (FDP) Swagger documentation. + HttpRequestUtils.handleResponseStatus(response); + } catch (Exception e) { + throw new RuntimeException(e); + } + } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java index 6f45893..8d15fd4 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java @@ -1,14 +1,16 @@ package nl.healthri.fdp.uploadschema.integrations; +import nl.healthri.fdp.uploadschema.config.fdp.Settings; import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; -import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; -import nl.healthri.fdp.uploadschema.dto.request.Schema.ReleaseSchemaRequest; -import nl.healthri.fdp.uploadschema.dto.request.Schema.UpdateSchemaRequest; -import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; -import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.Resource.ResourceRequest; +import nl.healthri.fdp.uploadschema.dto.Schema.ReleaseSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.Schema.UpdateSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.Settings.SettingsResponse; +import nl.healthri.fdp.uploadschema.dto.auth.LoginRequest; +import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.auth.LoginResponse; +import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; import java.util.List; @@ -25,4 +27,7 @@ public interface FdpClientInterface { ResourceResponse fetchResource(String resourceId); ResourceResponse insertResource(ResourceTask task, ResourceRequest resourceRequest ); void updateResource(ResourceTask task, ResourceResponse resourceResponse); + + SettingsResponse getSettings(); + void updateSettings(Settings settings); } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java index 9837db2..1268dfe 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java @@ -1,17 +1,19 @@ package nl.healthri.fdp.uploadschema.services; +import nl.healthri.fdp.uploadschema.config.fdp.Settings; import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; -import nl.healthri.fdp.uploadschema.dto.request.Resource.ResourceRequest; -import nl.healthri.fdp.uploadschema.dto.request.Schema.ReleaseSchemaRequest; -import nl.healthri.fdp.uploadschema.dto.request.Schema.UpdateSchemaRequest; -import nl.healthri.fdp.uploadschema.dto.request.auth.LoginRequest; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; +import nl.healthri.fdp.uploadschema.dto.Resource.ResourceRequest; +import nl.healthri.fdp.uploadschema.dto.Schema.ReleaseSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.Schema.UpdateSchemaRequest; +import nl.healthri.fdp.uploadschema.dto.Settings.SettingsResponse; +import nl.healthri.fdp.uploadschema.dto.auth.LoginRequest; +import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.auth.LoginResponse; import nl.healthri.fdp.uploadschema.integrations.FdpClientInterface; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; -import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -124,4 +126,11 @@ public void updateResource(ResourceTask task){ fdpClient.updateResource(task, resourceResponse); } + + public void updateSettings(Settings newSettings){ + SettingsResponse currentSettings = fdpClient.getSettings(); + Settings mergedSettings = newSettings.Merge(currentSettings); + + fdpClient.updateSettings(mergedSettings); + } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/FdpServiceInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpServiceInterface.java index ebb123e..5e65c71 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/FdpServiceInterface.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpServiceInterface.java @@ -1,9 +1,10 @@ package nl.healthri.fdp.uploadschema.services; +import nl.healthri.fdp.uploadschema.config.fdp.Settings; import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; import java.util.List; @@ -19,4 +20,6 @@ public interface FdpServiceInterface { List getAllResources(); void createResource(ResourceTask task); void updateResource(ResourceTask task); + + void updateSettings(Settings settings); } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index de50471..7764227 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -1,10 +1,9 @@ package nl.healthri.fdp.uploadschema.services; -import jakarta.annotation.Resource; import nl.healthri.fdp.uploadschema.domain.ResourceTask; -import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.utils.Properties; +import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.config.fdp.Properties; import nl.healthri.fdp.uploadschema.utils.ResourceInfo; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import org.slf4j.Logger; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java index 6e39257..281d2f2 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/SchemaToolService.java @@ -3,7 +3,7 @@ import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; import nl.healthri.fdp.uploadschema.utils.FileHandler; -import nl.healthri.fdp.uploadschema.utils.Properties; +import nl.healthri.fdp.uploadschema.config.fdp.Properties; import nl.healthri.fdp.uploadschema.utils.RdfUtils; import nl.healthri.fdp.uploadschema.utils.XlsToRdfUtils; import org.eclipse.rdf4j.model.Model; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java index eb23e74..93e28b9 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java @@ -3,9 +3,9 @@ import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.domain.ShapeTask; import nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.utils.*; -import nl.healthri.fdp.uploadschema.utils.Properties; +import nl.healthri.fdp.uploadschema.config.fdp.Properties; import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.model.util.Models; import org.slf4j.Logger; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java index 214beeb..d251b46 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java @@ -1,6 +1,6 @@ package nl.healthri.fdp.uploadschema.utils; -import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; import java.util.HashMap; import java.util.List; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java index d700210..ba372a7 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java @@ -1,7 +1,7 @@ package nl.healthri.fdp.uploadschema.utils; import nl.healthri.fdp.uploadschema.domain.Version; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; import java.util.HashMap; import java.util.List; diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index 6c4954b..a06b3a8 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -2,9 +2,9 @@ import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.Version; -import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.utils.Properties; +import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.config.fdp.Properties; import nl.healthri.fdp.uploadschema.utils.ResourceInfo; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java index f1a51d3..92c1d98 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java @@ -3,9 +3,9 @@ import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.domain.ShapeTask; import nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.utils.*; -import nl.healthri.fdp.uploadschema.utils.Properties; +import nl.healthri.fdp.uploadschema.config.fdp.Properties; import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.model.impl.LinkedHashModel; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/nl/healthri/fdp/uploadschema/utils/PropertiesYamlTest.java b/src/test/java/nl/healthri/fdp/uploadschema/utils/PropertiesYamlTest.java index 3fe0370..1a146d4 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/utils/PropertiesYamlTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/utils/PropertiesYamlTest.java @@ -1,5 +1,6 @@ package nl.healthri.fdp.uploadschema.utils; +import nl.healthri.fdp.uploadschema.config.fdp.Properties; import org.junit.jupiter.api.Test; import java.io.File; From 9465cc6e6bb62b1785777c41d2abb503de2e46b6 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Wed, 26 Nov 2025 12:56:23 +0100 Subject: [PATCH 39/51] refactor: Improvements on merging sources fromn existing FDP settings and new settings. --- .../fdp/uploadschema/config/fdp/Settings.java | 48 +++++++++---------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java b/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java index ce542b9..8a7d52a 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java @@ -11,6 +11,9 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.util.List; +import java.util.Map; + +import static java.util.stream.Collectors.toMap; public class Settings { private static Settings settings; @@ -122,43 +125,36 @@ public Settings Merge(SettingsResponse fdpSettings){ mergedSettings.forms.autocomplete.searchNamespace = fdpSettings.forms().autocomplete().searchNamespace(); - List mergedSources = - new java.util.ArrayList<>(); - - List existingSources = - mergedSettings.forms.autocomplete.sources; + List mergedSources = new java.util.ArrayList<>(); + List settingsSources = mergedSettings.forms.autocomplete.sources; + List fdpSources = fdpSettings.forms().autocomplete().sources(); - List incomingSources = - fdpSettings.forms().autocomplete().sources(); - - // todo: allow multiple rdf types? - java.util.Map incomingByRdfType = - incomingSources.stream().collect( - java.util.stream.Collectors.toMap( + // Creates map with RdfType as key and the Source as value + // Each source is mapped from SettingsResponse Source to Settings Source. + Map sourcesByRdfType = + fdpSources.stream() + .collect( + toMap( SettingsResponse.Forms.Autocomplete.Source::rdfType, - s -> { + source -> { Forms.Autocomplete.Source src = new Forms.Autocomplete.Source(); - src.rdfType = s.rdfType(); - src.sparqlEndpoint = s.sparqlEndpoint(); - src.sparqlQuery = s.sparqlQuery(); + src.rdfType = source.rdfType(); + src.sparqlEndpoint = source.sparqlEndpoint(); + src.sparqlQuery = source.sparqlQuery(); return src; } )); - if (existingSources != null) { - for (Forms.Autocomplete.Source existing : existingSources) { - if (incomingByRdfType.containsKey(existing.rdfType)) { - mergedSources.add(incomingByRdfType.get(existing.rdfType)); - incomingByRdfType.remove(existing.rdfType); - } else { - mergedSources.add(existing); - } + // Checks if each Source in Settings Source list is already the in FDP Source map sourcesByRdfType. + // If RdfType is already in sourceByRdfMap the Source is ignored, otherwise it's added. + if (settingsSources != null) { + for (Forms.Autocomplete.Source existing : settingsSources) { + Forms.Autocomplete.Source source = sourcesByRdfType.getOrDefault(existing.rdfType, existing); + mergedSources.add(source); } } - mergedSources.addAll(incomingByRdfType.values()); mergedSettings.forms.autocomplete.sources = mergedSources; - return this; } } From 242f35a30aacfe425077e0352ed0ae311719d18f Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Wed, 26 Nov 2025 14:38:58 +0100 Subject: [PATCH 40/51] feat: Added test cases --- .../fdp/uploadschema/config/fdp/Settings.java | 11 ----------- .../fdp/uploadschema/config/SettingsTest.java | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java diff --git a/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java b/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java index 8a7d52a..e515b2f 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java @@ -1,10 +1,6 @@ package nl.healthri.fdp.uploadschema.config.fdp; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.core.exc.StreamReadException; -import com.fasterxml.jackson.databind.DatabindException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import nl.healthri.fdp.uploadschema.dto.Settings.SettingsResponse; import java.io.File; @@ -43,33 +39,27 @@ public static class Ping { public List endpoints; public List endpointsFromConfig; public String interval; - } public static class Repository { public String type; - } public static class Search { public List filters; - } public static class Forms { public Autocomplete autocomplete; - public static class Autocomplete { public boolean searchNamespace; public List sources; - public static class Source { public String rdfType; public String sparqlEndpoint; public String sparqlQuery; - } } } @@ -82,7 +72,6 @@ public static Settings GetSettings(File file) throws IOException { } ObjectMapper mapper = new ObjectMapper(); settings = mapper.readValue(file, Settings.class); - } return settings; diff --git a/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java b/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java new file mode 100644 index 0000000..bca98ee --- /dev/null +++ b/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java @@ -0,0 +1,18 @@ +package nl.healthri.fdp.uploadschema.config; + +public class SettingsTest { + + public void DuplicateRdfTypeInFdpSettings_WhenMerging_ReturnsDuplicateKeyException(){} + + public void LocalSourceFoundInFdp_WhenMerging_ReturnsSettingsWithFdpSource(){} + + public void LocalSourceMissingInFdpSettings_WhenMerging_ReturnsSettingsWithLocalSource(){} + + public void FileNotFound_WhenGettingSettings_ThrowsFileNotFoundException(){} + + public void MalformedJsonFile_WhenGettingSettings_ThrowsIOException(){} + + public void ValidJsonFile_WhenGettingSettings_ReturnsSettings(){ + + } +} From f5680236a48dada57b15ee68dc20e92f6dc57075 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Tue, 2 Dec 2025 15:18:56 +0100 Subject: [PATCH 41/51] fix: resource merge feat: Added tests for settings --- .../fdp/uploadschema/config/fdp/Settings.java | 53 +++-- .../fdp/uploadschema/config/SettingsTest.java | 210 +++++++++++++++++- 2 files changed, 235 insertions(+), 28 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java b/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java index e515b2f..3a7af0e 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java @@ -6,8 +6,10 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import static java.util.stream.Collectors.toMap; @@ -64,6 +66,15 @@ public static class Source { } } + // Always returns the existing settings if already initialized. + public static Settings GetSettings(){ + if(settings == null){ + throw new NullPointerException("Settings instance is not set"); + } + + return settings; + } + // Always returns the existing settings if already initialized. public static Settings GetSettings(File file) throws IOException { if(settings == null){ @@ -116,34 +127,34 @@ public Settings Merge(SettingsResponse fdpSettings){ List mergedSources = new java.util.ArrayList<>(); List settingsSources = mergedSettings.forms.autocomplete.sources; - List fdpSources = fdpSettings.forms().autocomplete().sources(); // Creates map with RdfType as key and the Source as value // Each source is mapped from SettingsResponse Source to Settings Source. - Map sourcesByRdfType = - fdpSources.stream() - .collect( - toMap( - SettingsResponse.Forms.Autocomplete.Source::rdfType, - source -> { - Forms.Autocomplete.Source src = new Forms.Autocomplete.Source(); - src.rdfType = source.rdfType(); - src.sparqlEndpoint = source.sparqlEndpoint(); - src.sparqlQuery = source.sparqlQuery(); - return src; - } - )); - - // Checks if each Source in Settings Source list is already the in FDP Source map sourcesByRdfType. - // If RdfType is already in sourceByRdfMap the Source is ignored, otherwise it's added. + List fdpSourceList = new ArrayList<>(); + List fdpSources = fdpSettings.forms().autocomplete().sources(); + for (SettingsResponse.Forms.Autocomplete.Source source : fdpSources) { + Forms.Autocomplete.Source src = new Forms.Autocomplete.Source(); + src.rdfType = source.rdfType(); + src.sparqlEndpoint = source.sparqlEndpoint(); + src.sparqlQuery = source.sparqlQuery(); + mergedSettings.forms.autocomplete.sources.add(src); + } + + + // Checks if each Source in Settings is already the in mergedSettings resource. + // Adds to mergedSettings resource list if resource is not in merged settings. if (settingsSources != null) { - for (Forms.Autocomplete.Source existing : settingsSources) { - Forms.Autocomplete.Source source = sourcesByRdfType.getOrDefault(existing.rdfType, existing); - mergedSources.add(source); + for (Forms.Autocomplete.Source source : settingsSources) { + boolean exists = mergedSettings.forms.autocomplete.sources + .stream() + .anyMatch(s -> Objects.equals(s.rdfType, source.rdfType)); + + if (!exists) { + mergedSettings.forms.autocomplete.sources.add(source); + } } } - mergedSettings.forms.autocomplete.sources = mergedSources; return this; } } diff --git a/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java b/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java index bca98ee..f67ede9 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java @@ -1,18 +1,214 @@ package nl.healthri.fdp.uploadschema.config; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.DatabindException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import nl.healthri.fdp.uploadschema.config.fdp.Settings; +import nl.healthri.fdp.uploadschema.dto.Settings.SettingsResponse; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + public class SettingsTest { - public void DuplicateRdfTypeInFdpSettings_WhenMerging_ReturnsDuplicateKeyException(){} + @TempDir + File tempDir; + + // Helper to reset the static 'settings' instance + @BeforeEach + void resetSettingsSingleton() throws Exception { + Field settingsField = Settings.class.getDeclaredField("settings"); + settingsField.setAccessible(true); + settingsField.set(null, null); + } + + // Create a minimal SettingsResponse for merging + private SettingsResponse createMinimalFdpSettingsResponse() { + return new SettingsResponse( + "clientUrl", "persistentUrl", "appTitle", "appSubtitle", + "appTitleConfig", "appSubtitleConfig", + List.of(), + new SettingsResponse.Ping(true, List.of("e1"), List.of("e1c"), "1h"), + new SettingsResponse.Repository("type"), + new SettingsResponse.Search(List.of("f1")), + new SettingsResponse.Forms( + new SettingsResponse.Forms.Autocomplete( + true, + List.of( + new SettingsResponse.Forms.Autocomplete.Source("FdpRdfType1", "fsparql1", "fquery1") + ) + ) + ) + ); + } + + // Create a SettingsResponse with an RDF Type used twice + private SettingsResponse createFdpSettingsResponseWithDuplicates() { + return new SettingsResponse( + "clientUrl", "persistentUrl", "appTitle", "appSubtitle", + "appTitleConfig", "appSubtitleConfig", + List.of(), + new SettingsResponse.Ping(true, List.of("e1"), List.of("e1c"), "1h"), + new SettingsResponse.Repository("type"), + new SettingsResponse.Search(List.of("f1")), + new SettingsResponse.Forms( + new SettingsResponse.Forms.Autocomplete( + true, + List.of( + new SettingsResponse.Forms.Autocomplete.Source("DuplicateRdfType", "fsparql1", "fquery1"), + new SettingsResponse.Forms.Autocomplete.Source("DuplicateRdfType", "fsparql2", "fquery2") // DUPLICATE + ) + ) + ) + ); + } + + public File createFile(String jsonFdpSettings) throws IOException { + // Get initial settings loaded (they don't need sources for this test) + File validFile = new File(tempDir, "settings.json"); + try (FileWriter writer = new FileWriter(validFile)) { + writer.write(jsonFdpSettings); + } + + return validFile; + } + + @Test + public void DuplicateRdfTypeInFdpSettings_WhenMerging_ReturnsDuplicateKeyException() throws IOException { + // ARRANGE + String jsonFdpSettings = "{\"forms\": {\"autocomplete\": {\"sources\": []}}}"; + File file = createFile(jsonFdpSettings); + SettingsResponse fdpSettingsWithDuplicate = createFdpSettingsResponseWithDuplicates(); + + // ACT + Settings settings = Settings.GetSettings(file); + + // ACT & ASSERT + assertThrows(IllegalStateException.class, () -> { + settings.Merge(fdpSettingsWithDuplicate); + }); + } + + @Test + public void SourceFoundInFdp_WhenMerging_ReturnsSettingsWithFdpSource() throws IOException { + // ARRANGE + final String localRdfType = "CommonRdfType"; + final String localQuery = "LocalQuery"; + + final String fdpQuery = "FdpQuery"; - public void LocalSourceFoundInFdp_WhenMerging_ReturnsSettingsWithFdpSource(){} + String jsonFdpSettings = "{\"forms\": {\"autocomplete\": {\"sources\": [{\"rdfType\": \"" + localRdfType + "\", \"sparqlQuery\": \"" + localQuery + "\"}]}}}"; + File file = createFile(jsonFdpSettings); + Settings settings = Settings.GetSettings(file); - public void LocalSourceMissingInFdpSettings_WhenMerging_ReturnsSettingsWithLocalSource(){} - public void FileNotFound_WhenGettingSettings_ThrowsFileNotFoundException(){} + // Setup FDP Settings with the same rdfType, but different query + SettingsResponse fdpSettings = new SettingsResponse( + "clientUrl", "persistentUrl", "appTitle", "appSubtitle", + "appTitleConfig", "appSubtitleConfig", + List.of(), + new SettingsResponse.Ping(true, List.of(), List.of(), "1h"), + new SettingsResponse.Repository("type"), + new SettingsResponse.Search(List.of()), + new SettingsResponse.Forms( + new SettingsResponse.Forms.Autocomplete( + true, + List.of( + new SettingsResponse.Forms.Autocomplete.Source(localRdfType, "fsparql", fdpQuery) + ) + ) + ) + ); + + // ACT + settings = settings.Merge(fdpSettings); + + // ASSERT + Settings.Forms.Autocomplete.Source mergedSource = settings.forms.autocomplete.sources.get(0); + assertEquals(1, settings.forms.autocomplete.sources.size(), "Should only have one source after merge."); + assertEquals(localRdfType, mergedSource.rdfType, "RDF type should be retained."); + assertEquals(fdpQuery, mergedSource.sparqlQuery, "Query from FDP settings should be used."); + } + + @Test + public void SourceMissingInFdpSettings_WhenMerging_ReturnsSettingsWithSource() throws IOException { + // ARRANGE + final String localRdfType = "LocalOnlyRdfType"; + final String localQuery = "LocalQuery"; + + String jsonFdpSettings = "{\"forms\": {\"autocomplete\": {\"sources\": [{\"rdfType\": \"" + localRdfType + "\", \"sparqlQuery\": \"" + localQuery + "\"}]}}}"; + File file = createFile(jsonFdpSettings); + Settings settings = Settings.GetSettings(file); + SettingsResponse fdpSettings = createMinimalFdpSettingsResponse(); + + // ACT + settings = settings.Merge(fdpSettings); + + // ASSERT + assertEquals(2, settings.forms.autocomplete.sources.size(), "Should have both local and FDP source."); + + // Check if the local source is preserved + Settings.Forms.Autocomplete.Source localSource = settings.forms.autocomplete.sources.stream() + .filter(s -> s.rdfType.equals(localRdfType)) + .findFirst().orElseThrow(() -> new AssertionError("Local source not found in merged settings")); + assertEquals(localQuery, localSource.sparqlQuery, "Local source's query should be preserved."); + + // Check if the FDP source is present + settings.forms.autocomplete.sources.stream() + .filter(s -> s.rdfType.equals("FdpRdfType1")) + .findFirst().orElseThrow(() -> new AssertionError("FDP source not found in merged settings")); + } + + @Test + public void FileNotFound_WhenGettingSettings_ThrowsFileNotFoundException() throws IOException { + // ARRANGE + File nonExistentFile = new File(tempDir, "nonExistent.json"); + + // ACT && ASSERT + assertThrows(FileNotFoundException.class, () -> { + Settings.GetSettings(nonExistentFile); + }); + } + + @Test + public void MalformedJsonFile_WhenGettingSettings_ThrowsIOException() throws IOException { + // ARRANGE + String jsonFdpSettings = "{ \"forms\": { \"autocomplete\": \"invalid"; + File file = createFile(jsonFdpSettings); + SettingsResponse fdpSettings = createMinimalFdpSettingsResponse(); + + // ACT & ASSERT + assertThrows(JsonMappingException.class, () -> { + Settings.GetSettings(file); + }); + } + + @Test + public void ValidJsonFile_WhenGettingSettings_ReturnsSettings() throws IOException { + // ARRANGE + final String expectedAppTitle = "TestTitle"; + String jsonFdpSettings = "{\"appTitle\":\"" + expectedAppTitle + "\", \"forms\": {}}"; + File file = createFile(jsonFdpSettings); - public void MalformedJsonFile_WhenGettingSettings_ThrowsIOException(){} + // ACT + Settings settings = Settings.GetSettings(file); - public void ValidJsonFile_WhenGettingSettings_ReturnsSettings(){ + // ASSERT + assertNotNull(settings, "Settings should not be null."); + assertEquals(expectedAppTitle, settings.appTitle, "Settings appTitle should match the file content."); + // Check singleton logic (calling again returns same instance) + Settings settings2 = Settings.GetSettings(); + assertSame(settings, settings2, "Subsequent calls should return the same singleton instance."); } -} +} \ No newline at end of file From 20e2e7b75d78039221023f8cf1a47f8402ecde4f Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Tue, 2 Dec 2025 15:33:34 +0100 Subject: [PATCH 42/51] fix: Test removed for duplicate resources in FdpSettings --- .../fdp/uploadschema/config/SettingsTest.java | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java b/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java index f67ede9..825e819 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java @@ -83,22 +83,6 @@ public File createFile(String jsonFdpSettings) throws IOException { return validFile; } - @Test - public void DuplicateRdfTypeInFdpSettings_WhenMerging_ReturnsDuplicateKeyException() throws IOException { - // ARRANGE - String jsonFdpSettings = "{\"forms\": {\"autocomplete\": {\"sources\": []}}}"; - File file = createFile(jsonFdpSettings); - SettingsResponse fdpSettingsWithDuplicate = createFdpSettingsResponseWithDuplicates(); - - // ACT - Settings settings = Settings.GetSettings(file); - - // ACT & ASSERT - assertThrows(IllegalStateException.class, () -> { - settings.Merge(fdpSettingsWithDuplicate); - }); - } - @Test public void SourceFoundInFdp_WhenMerging_ReturnsSettingsWithFdpSource() throws IOException { // ARRANGE @@ -134,10 +118,7 @@ public void SourceFoundInFdp_WhenMerging_ReturnsSettingsWithFdpSource() throws I settings = settings.Merge(fdpSettings); // ASSERT - Settings.Forms.Autocomplete.Source mergedSource = settings.forms.autocomplete.sources.get(0); - assertEquals(1, settings.forms.autocomplete.sources.size(), "Should only have one source after merge."); - assertEquals(localRdfType, mergedSource.rdfType, "RDF type should be retained."); - assertEquals(fdpQuery, mergedSource.sparqlQuery, "Query from FDP settings should be used."); + assertEquals(2, settings.forms.autocomplete.sources.size(), "Should have 1 resource from settings and 1 resource from fdpSettings."); } @Test From 86bfd1e2f1f501555341a33396be1b8ba4acf1b6 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Tue, 6 Jan 2026 16:36:33 +0100 Subject: [PATCH 43/51] refactor: improved exception handling logging and InterruptedException thread exception handling --- .../uploadschema/integrations/FdpClient.java | 68 +++++- .../fdp/uploadschema/utils/FileHandler.java | 9 +- .../services/ShapeUpdateInsertTaskTest.java | 214 ------------------ 3 files changed, 63 insertions(+), 228 deletions(-) delete mode 100644 src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java index b69ae72..79e5a07 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java @@ -17,7 +17,9 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; +import java.io.IOException; import java.net.URI; +import java.net.URISyntaxException; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; @@ -78,7 +80,12 @@ public LoginResponse getAuthToken(LoginRequest loginRequest) { // Maps response body to object return this.objectMapper.readValue(response.body(), LoginResponse.class); - } catch (Exception e) { + } catch (IOException | URISyntaxException e) { + logger.error("Failed to get authorization token: {}", e.getMessage()); + throw new RuntimeException(e); + } catch (InterruptedException e){ + logger.error("Thread was interrupted while getting authorization token: {}", e.getMessage()); + Thread.currentThread().interrupt(); throw new RuntimeException(e); } } @@ -107,7 +114,12 @@ public List fetchSchemas() { // Maps response body to object return List.of(objectMapper.readValue(response.body(), SchemaDataResponse[].class)); - } catch (Exception e) { + } catch (IOException | URISyntaxException e) { + logger.error("Failed to fetch schemas: {}", e.getMessage()); + throw new RuntimeException(e); + } catch (InterruptedException e){ + logger.error("Thread was interrupted while fetching schemas: {}", e.getMessage()); + Thread.currentThread().interrupt(); throw new RuntimeException(e); } } @@ -144,14 +156,16 @@ public ResourceResponse insertSchema(ShapeTask task, UpdateSchemaRequest updateS // Maps response body to object return objectMapper.readValue(response.body(), ResourceResponse.class); - } catch (Exception e) { + } catch (IOException | URISyntaxException e) { + logger.error("Failed to insert schema: {}", e.getMessage()); + throw new RuntimeException(e); + } catch (InterruptedException e){ + logger.error("Thread was interrupted while inserting schemas: {}", e.getMessage()); + Thread.currentThread().interrupt(); throw new RuntimeException(e); } } - - - public void updateSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest) { logger.info("Updating shape {} in FDP", task.shape); @@ -177,7 +191,12 @@ public void updateSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); - } catch (Exception e) { + } catch (IOException | URISyntaxException e) { + logger.error("Failed to update schema: {}", e.getMessage()); + throw new RuntimeException(e); + } catch (InterruptedException e){ + logger.error("Thread was interrupted while updating schema: {}", e.getMessage()); + Thread.currentThread().interrupt(); throw new RuntimeException(e); } } @@ -208,7 +227,12 @@ public void releaseSchema(ShapeTask task, ReleaseSchemaRequest releaseSchemaRequ // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); - } catch (Exception e) { + } catch (IOException | URISyntaxException e) { + logger.error("Failed to release schema: {}", e.getMessage()); + throw new RuntimeException(e); + } catch (InterruptedException e){ + logger.error("Thread was interrupted with release schema: {}", e.getMessage()); + Thread.currentThread().interrupt(); throw new RuntimeException(e); } } @@ -237,7 +261,12 @@ public List fetchResources() { // Map response to body return List.of(objectMapper.readValue(response.body(), ResourceResponse[].class)); - } catch (Exception e) { + } catch (IOException | URISyntaxException e) { + logger.error("Failed to fetch resources: {}", e.getMessage()); + throw new RuntimeException(e); + } catch (InterruptedException e){ + logger.error("Thread was interrupted while fetching resources: {}", e.getMessage()); + Thread.currentThread().interrupt(); throw new RuntimeException(e); } } @@ -266,7 +295,12 @@ public ResourceResponse fetchResource(String resourceId){ // Maps response body to object return objectMapper.readValue(response.body(), ResourceResponse.class); - } catch (Exception e) { + } catch (IOException | URISyntaxException e) { + logger.error("Failed to fetch resource: {}", e.getMessage()); + throw new RuntimeException(e); + } catch (InterruptedException e){ + logger.error("Thread was interrupted while fetching resource: {}", e.getMessage()); + Thread.currentThread().interrupt(); throw new RuntimeException(e); } } @@ -300,7 +334,12 @@ public ResourceResponse insertResource(ResourceTask task, ResourceRequest resour // Maps response body to object return objectMapper.readValue(response.body(), ResourceResponse.class); - } catch (Exception e) { + } catch (IOException | URISyntaxException e) { + logger.error("Failed to insert resources: {}", e.getMessage()); + throw new RuntimeException(e); + } catch (InterruptedException e){ + logger.error("Thread was interrupted while inserting schema: {}", e.getMessage()); + Thread.currentThread().interrupt(); throw new RuntimeException(e); } } @@ -330,7 +369,12 @@ public void updateResource(ResourceTask task, ResourceResponse resourceResponse) // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); - } catch (Exception e) { + } catch (IOException | URISyntaxException e) { + logger.error("Failed to update resources: {}", e.getMessage()); + throw new RuntimeException(e); + } catch (InterruptedException e){ + logger.error("Thread was interrupted while updating resource: {}", e.getMessage()); + Thread.currentThread().interrupt(); throw new RuntimeException(e); } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java index e414a4f..85ce130 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/FileHandler.java @@ -93,8 +93,13 @@ private InputStream getInputStream(URI uri) throws IOException { } else { throw new IOException("Failed to fetch file: " + response.statusCode()); } - } catch (InterruptedException ie) { - throw new RuntimeException(ie); + } catch (IOException e) { + logger.error("Failed to get input stream: {}", e.getMessage()); + throw new RuntimeException(e); + } catch (InterruptedException e){ + logger.error("Thread was interrupted while getting input stream: {}", e.getMessage()); + Thread.currentThread().interrupt(); + throw new RuntimeException(e); } } else { return new FileInputStream(Paths.get(uri).toFile()); diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java deleted file mode 100644 index fc2e646..0000000 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeUpdateInsertTaskTest.java +++ /dev/null @@ -1,214 +0,0 @@ -package nl.healthri.fdp.uploadschema.services; - -import nl.healthri.fdp.uploadschema.integrations.FdpClient; -import nl.healthri.fdp.uploadschema.domain.Version; -import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.utils.FileHandler; -import nl.healthri.fdp.uploadschema.utils.Properties; -import nl.healthri.fdp.uploadschema.utils.RdfUtils; -import nl.healthri.fdp.uploadschema.utils.SchemaInfo; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import java.net.URI; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -class ShapeUpdateInsertTaskTest { - - /** - * Tests the functionality of the `ShapeUpdateInsertTask.createTasks` - * The test uses mocking to simulate: - *

- * - Fetching schema data from an FDP (Fair Data Point). - * - RDF model reading from files via a `FileHandler`. - *

- * The schema is present on FDP, but the schema of the file is different - * so the task will be labeled with "UPDATE" - */ - @Test - void testCreateTasks_updated_shape() { - // Mock Properties - Properties props = Mockito.mock(Properties.class); - props.schemasToPublish = List.of("TestShape"); - Mockito.when(props.getFiles()).thenReturn(Map.of("TestShape", List.of(URI.create("file:test.ttl")))); - Mockito.when(props.getVersion()).thenReturn(new Version("2.0.0")); - Mockito.when(props.getParents("TestShape")).thenReturn(Set.of("ParentShape")); - - // Mock FDP and its fetchSchemaFromFDP result - SchemaInfo shapesOnFdp = createFdpShapeMap( - createFdpResponse("TestShape", "", "1.0.0", "uuid")); - - FdpClient fdpClient = Mockito.mock(FdpClient.class); - Mockito.when(fdpClient.fetchSchemas()).thenReturn(shapesOnFdp); - - // Mock FileHandler - FileHandler fileHandler = Mockito.mock(FileHandler.class); - Mockito.when(fileHandler.readFiles(Mockito.anyList())).thenReturn(RdfUtils.fromTurtleString(getShapeModel2())); - - // Run createTasks - List tasks = ShapeUpdateInsertTask.createTasks(props, fdpClient, fileHandler); - - // Assert - assertEquals(1, tasks.size()); - ShapeUpdateInsertTask task = tasks.getFirst(); - assertEquals("TestShape", task.shape); - assertEquals(new Version("2.0.0"), task.version); - assertEquals(getShapeModel2(), task.model); - assertEquals(ShapeUpdateInsertTask.ShapeStatus.UPDATE, task.status); - } - - /** - * Tests the functionality of the `ShapeUpdateInsertTask.createTasks` - * The test uses mocking to simulate: - *

- * - Fetching schema data from an FDP (Fair Data Point). - * - RDF model reading from files via a `FileHandler`. - *

- * The schema is on FDP and is the same as from the file. So it the task will be labeled with "SAME" - */ - @Test - void testCreateTasks_identical_shape() { - // Mock Properties - Properties props = Mockito.mock(Properties.class); - props.schemasToPublish = List.of("TestShape"); - Mockito.when(props.getFiles()).thenReturn(Map.of("TestShape", List.of(URI.create("file:test.ttl")))); - Mockito.when(props.getVersion()).thenReturn(new Version("2.0.0")); - Mockito.when(props.getParents("TestShape")).thenReturn(Set.of("ParentShape")); - - // Mock FDP and its fetchSchemaFromFDP result - SchemaInfo shapesOnFdp = createFdpShapeMap( - createFdpResponse("TestShape", getShapeModel1(), "1.0.0", "uuid")); - - FdpClient fdpClient = Mockito.mock(FdpClient.class); - Mockito.when(fdpClient.fetchSchemas()).thenReturn(shapesOnFdp); - - // Mock FileHandler - FileHandler fileHandler = Mockito.mock(FileHandler.class); - Mockito.when(fileHandler.readFiles(Mockito.anyList())).thenReturn(RdfUtils.fromTurtleString(getShapeModel1())); - - // Run createTasks - List tasks = ShapeUpdateInsertTask.createTasks(props, fdpClient, fileHandler); - - // Assert - assertEquals(1, tasks.size()); - ShapeUpdateInsertTask task = tasks.getFirst(); - assertEquals("TestShape", task.shape); - assertEquals(new Version("2.0.0"), task.version); - assertEquals(getShapeModel1(), task.model); - assertEquals(ShapeUpdateInsertTask.ShapeStatus.SAME, task.status); - } - - /** - * Tests the functionality of the `ShapeUpdateInsertTask.createTasks` - * The test uses mocking to simulate: - *

- * - Fetching schema data from an FDP (Fair Data Point). - * - RDF model reading from files via a `FileHandler`. - *

- * The schema is not present on the FDP, so the task will be labeled with "SAME" - */ - @Test - void testCreateTasks_new() { - // Mock Properties - Properties props = Mockito.mock(Properties.class); - props.schemasToPublish = List.of("TestShape"); - Mockito.when(props.getFiles()).thenReturn(Map.of("TestShape", List.of(URI.create("file:test.ttl")))); - Mockito.when(props.getVersion()).thenReturn(new Version("2.0.0")); - Mockito.when(props.getParents("TestShape")).thenReturn(Set.of("ParentShape")); - - // Mock FDP and its fetchSchemaFromFDP result - SchemaInfo shapesOnFdp = createFdpShapeMap( - createFdpResponse("JustAnotherShape", "", "1.0.0", "uuid")); - - FdpClient fdpClient = Mockito.mock(FdpClient.class); - Mockito.when(fdpClient.fetchSchemas()).thenReturn(shapesOnFdp); - - // Mock FileHandler - FileHandler fileHandler = Mockito.mock(FileHandler.class); - Mockito.when(fileHandler.readFiles(Mockito.anyList())).thenReturn(RdfUtils.fromTurtleString(getShapeModel2())); - - // Run createTasks - List tasks = ShapeUpdateInsertTask.createTasks(props, fdpClient, fileHandler); - - // Assert - assertEquals(1, tasks.size()); - ShapeUpdateInsertTask task = tasks.getFirst(); - assertEquals("TestShape", task.shape); - assertEquals(new Version("2.0.0"), task.version); - assertEquals(getShapeModel2(), task.model); - assertEquals(ShapeUpdateInsertTask.ShapeStatus.INSERT, task.status); - } - - private SchemaInfo createFdpShapeMap(SchemaDataResponse... responses) { - return new SchemaInfo(responses); - } - - private SchemaDataResponse createFdpResponse(String name, String definition, String version, String uuid) { - SchemaDataResponse.Latest latest = new SchemaDataResponse.Latest(uuid, - version, uuid, - "", - name, true, false, true, - "", "", "", definition, "", null, null, "", ""); - - return new SchemaDataResponse(uuid, name, latest, null, null, null, null); - } - - private String getShapeModel1() { - return linter(""" - @prefix ex: . - @prefix sh: . - @prefix xsd: . - @prefix foaf: . - - ex:PersonShape a sh:NodeShape ; - sh:targetClass foaf:Person ; - sh:property ex:NamePropertyShape ; - sh:property ex:AgePropertyShape . - - ex:NamePropertyShape a sh:PropertyShape ; - sh:path foaf:name ; - sh:datatype xsd:string ; - sh:minCount 1 . - - ex:AgePropertyShape a sh:PropertyShape ; - sh:path foaf:age ; - sh:datatype xsd:integer ; - sh:minInclusive 0 ; - sh:maxCount 1 ."""); - } - - private String linter(String s) { - //make sure the model is properly formatted - return RdfUtils.modelAsTurtleString(RdfUtils.fromTurtleString(s)); - } - - private String getShapeModel2() { - - return linter(""" - @prefix ex: . - @prefix sh: . - @prefix xsd: . - @prefix foaf: . - - ex:PersonShape a sh:NodeShape ; - sh:targetClass foaf:Person ; - sh:property ex:NamePropertyShape ; - sh:property ex:AgePropertyShape . - - ex:NamePropertyShape a sh:PropertyShape ; - sh:path foaf:name ; - sh:datatype xsd:string ; - sh:minCount 100 . - - ex:AgePropertyShape a sh:PropertyShape ; - sh:path foaf:age ; - sh:datatype xsd:integer ; - sh:minInclusive 0 ; - sh:maxCount 1 ."""); - } -} - From 36460055f9cc762a54ddec8bec36a531e18f2bf8 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Wed, 7 Jan 2026 10:37:16 +0100 Subject: [PATCH 44/51] Refactor: change client request headers to use constants --- .../fdp/uploadschema/SchemaTools.java | 5 -- .../uploadschema/integrations/FdpClient.java | 57 +++++++++---------- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index d7c2613..7ba10b7 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -8,8 +8,6 @@ import nl.healthri.fdp.uploadschema.services.ShapeTaskService; import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import picocli.CommandLine; import java.io.File; @@ -22,9 +20,6 @@ @CommandLine.Command(name = "SchemaTools utility that create FDP ready Shacls and upload them the the FDP.", mixinStandardHelpOptions = true, version = "SchemaTool v1.0") public class SchemaTools implements Runnable { - - private static final Logger logger = LoggerFactory.getLogger(SchemaTools.class); - @CommandLine.Option(names = {"-i", "--input"}, defaultValue = "./Properties.yaml", description = "location of the Property.yaml file (default: ${DEFAULT-VALUE})") File propertyFile; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java index 79e5a07..c388bf2 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java @@ -13,6 +13,8 @@ import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; import nl.healthri.fdp.uploadschema.utils.HttpRequestUtils; +import org.apache.http.HttpHeaders; +import org.apache.http.entity.ContentType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -25,9 +27,6 @@ import java.net.http.HttpResponse; import java.util.*; - -// TODO: Throw client exception instead of Runtimeexception (otherwise you hide the error encountered) - @Component public class FdpClient implements FdpClientInterface { private final HttpClient client; @@ -66,8 +65,8 @@ public LoginResponse getAuthToken(LoginRequest loginRequest) { HttpRequest request = HttpRequest.newBuilder() .POST(body) .uri(uri) - .header("accept", "application/json") - .header("Content-Type", "application/json") + .header(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()) .build(); @@ -101,9 +100,9 @@ public List fetchSchemas() { HttpRequest request = HttpRequest.newBuilder() .GET() .uri(uri) - .header("accept", "application/json") - .header("Content-Type", "application/json") - .header("Authorization", this.authToken) + .header(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.AUTHORIZATION, this.authToken) .build(); // Sends request created through the client @@ -143,9 +142,9 @@ public ResourceResponse insertSchema(ShapeTask task, UpdateSchemaRequest updateS HttpRequest request = HttpRequest.newBuilder() .POST(body) .uri(uri) - .header("accept", "application/json") - .header("Content-Type", "application/json") - .header("Authorization", this.authToken) + .header(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.AUTHORIZATION, this.authToken) .build(); // Sends request @@ -181,9 +180,9 @@ public void updateSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest HttpRequest request = HttpRequest.newBuilder() .PUT(body) .uri(uri) - .header("Accept", "application/json") - .header("Content-Type", "application/json") - .header("Authorization", this.authToken) + .header(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.AUTHORIZATION, this.authToken) .build(); // Sends request @@ -216,9 +215,9 @@ public void releaseSchema(ShapeTask task, ReleaseSchemaRequest releaseSchemaRequ HttpRequest request = HttpRequest.newBuilder() .POST(body) .uri(uri) - .header("Accept", "application/json") - .header("Content-Type", "application/json") - .header("Authorization", this.authToken) + .header(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.AUTHORIZATION, this.authToken) .build(); // Sends request @@ -248,9 +247,9 @@ public List fetchResources() { HttpRequest request = HttpRequest.newBuilder() .GET() .uri(uri) - .header("accept", "application/json") - .header("Content-Type", "application/json") - .header("Authorization", this.authToken) + .header(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.AUTHORIZATION, this.authToken) .build(); // Sends request @@ -282,9 +281,9 @@ public ResourceResponse fetchResource(String resourceId){ HttpRequest request = HttpRequest.newBuilder() .GET() .uri(uri) - .header("accept", "application/json") - .header("Content-Type", "application/json") - .header("Authorization", this.authToken) + .header(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.AUTHORIZATION, this.authToken) .build(); // Sends request @@ -321,9 +320,9 @@ public ResourceResponse insertResource(ResourceTask task, ResourceRequest resour HttpRequest request = HttpRequest.newBuilder() .POST(body) .uri(uri) - .header("accept", "application/json") - .header("content-type", "application/json") - .header("authorization", this.authToken) + .header(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.AUTHORIZATION, this.authToken) .build(); // Sends request @@ -359,9 +358,9 @@ public void updateResource(ResourceTask task, ResourceResponse resourceResponse) HttpRequest request = HttpRequest.newBuilder() .PUT(body) .uri(uri) - .header("accept", "application/json") - .header("Content-Type", "application/json") - .header("Authorization", this.authToken) + .header(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()) + .header(HttpHeaders.AUTHORIZATION, this.authToken) .build(); // Sends request From a024a6c44e59949cf3cc0036371a3aa3bfcc318d Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Thu, 8 Jan 2026 16:40:20 +0100 Subject: [PATCH 45/51] refactor: improved error logging and handling and changed HttpHeader and content type usage to constants --- .../fdp/uploadschema/SchemaTools.java | 11 ++- .../uploadschema/integrations/FdpClient.java | 78 ++++++++----------- .../integrations/FdpClientInterface.java | 19 ++--- .../exceptions/FdpClientException.java | 9 +++ .../fdp/uploadschema/services/FdpService.java | 50 ++++++------ .../services/ResourceTaskService.java | 9 +-- 6 files changed, 86 insertions(+), 90 deletions(-) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/integrations/exceptions/FdpClientException.java diff --git a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java index 7ba10b7..4e61108 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/SchemaTools.java @@ -2,12 +2,15 @@ import com.fasterxml.jackson.databind.ObjectMapper; import nl.healthri.fdp.uploadschema.integrations.FdpClient; +import nl.healthri.fdp.uploadschema.integrations.exceptions.FdpClientException; import nl.healthri.fdp.uploadschema.services.FdpService; import nl.healthri.fdp.uploadschema.services.ResourceTaskService; import nl.healthri.fdp.uploadschema.services.SchemaToolService; import nl.healthri.fdp.uploadschema.services.ShapeTaskService; import nl.healthri.fdp.uploadschema.utils.FileHandler; import nl.healthri.fdp.uploadschema.utils.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import picocli.CommandLine; import java.io.File; @@ -39,6 +42,8 @@ public class SchemaTools implements Runnable { @CommandLine.Option(names = {"-f", "--force"}, defaultValue = "false", description = "Force upload even if schema has not changed") boolean force; + private static final Logger logger = LoggerFactory.getLogger(SchemaTools.class); + public static void main(String... args) { var cmd = new CommandLine(new SchemaTools()); System.exit(cmd.execute(args)); @@ -75,8 +80,10 @@ public void run() { case SCHEMA -> schemaToolService.createOrUpdateSchemas(force); case RESOURCE -> schemaToolService.addResourceDescriptions(); } - } catch (IOException io) { - throw new RuntimeException(io); + } catch (IOException e) { + logger.error("Unexpected error: {}", e.getMessage()); + } catch (FdpClientException e){ + logger.error("FDP Connection Error: {}", e.getMessage()); } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java index c388bf2..05a3705 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java @@ -11,6 +11,7 @@ import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; +import nl.healthri.fdp.uploadschema.integrations.exceptions.FdpClientException; import nl.healthri.fdp.uploadschema.utils.HttpRequestUtils; import org.apache.http.HttpHeaders; @@ -80,12 +81,10 @@ public LoginResponse getAuthToken(LoginRequest loginRequest) { return this.objectMapper.readValue(response.body(), LoginResponse.class); } catch (IOException | URISyntaxException e) { - logger.error("Failed to get authorization token: {}", e.getMessage()); - throw new RuntimeException(e); - } catch (InterruptedException e){ - logger.error("Thread was interrupted while getting authorization token: {}", e.getMessage()); + throw new FdpClientException("Failed to reach FDP during authentication", e); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException(e); + throw new FdpClientException("Authentication process was interrupted", e); } } @@ -113,13 +112,12 @@ public List fetchSchemas() { // Maps response body to object return List.of(objectMapper.readValue(response.body(), SchemaDataResponse[].class)); + } catch (IOException | URISyntaxException e) { - logger.error("Failed to fetch schemas: {}", e.getMessage()); - throw new RuntimeException(e); - } catch (InterruptedException e){ - logger.error("Thread was interrupted while fetching schemas: {}", e.getMessage()); + throw new FdpClientException("Failed to reach FDP while fetching schemas", e); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException(e); + throw new FdpClientException("Request to fetch schemas was interrupted", e); } } @@ -156,12 +154,10 @@ public ResourceResponse insertSchema(ShapeTask task, UpdateSchemaRequest updateS // Maps response body to object return objectMapper.readValue(response.body(), ResourceResponse.class); } catch (IOException | URISyntaxException e) { - logger.error("Failed to insert schema: {}", e.getMessage()); - throw new RuntimeException(e); - } catch (InterruptedException e){ - logger.error("Thread was interrupted while inserting schemas: {}", e.getMessage()); + throw new FdpClientException("Failed to reach FDP while inserting schema for " + task.shape, e); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException(e); + throw new FdpClientException("Schema insertion was interrupted", e); } } @@ -191,12 +187,10 @@ public void updateSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); } catch (IOException | URISyntaxException e) { - logger.error("Failed to update schema: {}", e.getMessage()); - throw new RuntimeException(e); - } catch (InterruptedException e){ - logger.error("Thread was interrupted while updating schema: {}", e.getMessage()); + throw new FdpClientException("Failed to reach FDP while updating schema for " + task.shape, e); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException(e); + throw new FdpClientException("Schema update was interrupted", e); } } @@ -226,13 +220,11 @@ public void releaseSchema(ShapeTask task, ReleaseSchemaRequest releaseSchemaRequ // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); - } catch (IOException | URISyntaxException e) { - logger.error("Failed to release schema: {}", e.getMessage()); - throw new RuntimeException(e); - } catch (InterruptedException e){ - logger.error("Thread was interrupted with release schema: {}", e.getMessage()); + } catch (IOException | URISyntaxException e) { + throw new FdpClientException("Failed to reach FDP while releasing schema " + task.shape, e); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException(e); + throw new FdpClientException("Schema release was interrupted", e); } } @@ -260,13 +252,11 @@ public List fetchResources() { // Map response to body return List.of(objectMapper.readValue(response.body(), ResourceResponse[].class)); - } catch (IOException | URISyntaxException e) { - logger.error("Failed to fetch resources: {}", e.getMessage()); - throw new RuntimeException(e); - } catch (InterruptedException e){ - logger.error("Thread was interrupted while fetching resources: {}", e.getMessage()); + } catch (IOException | URISyntaxException e) { + throw new FdpClientException("Failed to reach FDP while fetching resources", e); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException(e); + throw new FdpClientException("Resource fetch was interrupted", e); } } @@ -295,12 +285,10 @@ public ResourceResponse fetchResource(String resourceId){ // Maps response body to object return objectMapper.readValue(response.body(), ResourceResponse.class); } catch (IOException | URISyntaxException e) { - logger.error("Failed to fetch resource: {}", e.getMessage()); - throw new RuntimeException(e); - } catch (InterruptedException e){ - logger.error("Thread was interrupted while fetching resource: {}", e.getMessage()); + throw new FdpClientException("Failed to reach FDP while fetching resource " + resourceId, e); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException(e); + throw new FdpClientException("Resource fetch was interrupted", e); } } @@ -334,12 +322,10 @@ public ResourceResponse insertResource(ResourceTask task, ResourceRequest resour // Maps response body to object return objectMapper.readValue(response.body(), ResourceResponse.class); } catch (IOException | URISyntaxException e) { - logger.error("Failed to insert resources: {}", e.getMessage()); - throw new RuntimeException(e); - } catch (InterruptedException e){ - logger.error("Thread was interrupted while inserting schema: {}", e.getMessage()); + throw new FdpClientException("Failed to reach FDP while inserting resource " + task.resource, e); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException(e); + throw new FdpClientException("Resource insertion was interrupted", e); } } @@ -369,12 +355,10 @@ public void updateResource(ResourceTask task, ResourceResponse resourceResponse) // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); } catch (IOException | URISyntaxException e) { - logger.error("Failed to update resources: {}", e.getMessage()); - throw new RuntimeException(e); - } catch (InterruptedException e){ - logger.error("Thread was interrupted while updating resource: {}", e.getMessage()); + throw new FdpClientException("Failed to reach FDP while updating resource " + task.resource, e); + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - throw new RuntimeException(e); + throw new FdpClientException("Resource update was interrupted", e); } } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java index 6f45893..adccf75 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java @@ -9,20 +9,21 @@ import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.integrations.exceptions.FdpClientException; import java.util.List; public interface FdpClientInterface { void setAuthToken(LoginResponse loginResponse); - LoginResponse getAuthToken(LoginRequest loginRequest); + LoginResponse getAuthToken(LoginRequest loginRequest) throws FdpClientException; - List fetchSchemas(); - ResourceResponse insertSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest); - void updateSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest); - void releaseSchema(ShapeTask task, ReleaseSchemaRequest releaseSchemaRequest); + List fetchSchemas() throws FdpClientException; + ResourceResponse insertSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest) throws FdpClientException; + void updateSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest) throws FdpClientException; + void releaseSchema(ShapeTask task, ReleaseSchemaRequest releaseSchemaRequest) throws FdpClientException; - List fetchResources(); - ResourceResponse fetchResource(String resourceId); - ResourceResponse insertResource(ResourceTask task, ResourceRequest resourceRequest ); - void updateResource(ResourceTask task, ResourceResponse resourceResponse); + List fetchResources() throws FdpClientException; + ResourceResponse fetchResource(String resourceId) throws FdpClientException; + ResourceResponse insertResource(ResourceTask task, ResourceRequest resourceRequest) throws FdpClientException; + void updateResource(ResourceTask task, ResourceResponse resourceResponse) throws FdpClientException; } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integrations/exceptions/FdpClientException.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/exceptions/FdpClientException.java new file mode 100644 index 0000000..0c1f471 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/exceptions/FdpClientException.java @@ -0,0 +1,9 @@ +package nl.healthri.fdp.uploadschema.integrations.exceptions; + +// FdpClientException.java +public class FdpClientException extends RuntimeException { + public FdpClientException(String message, Throwable cause) { + super(message, cause); + } +} + diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java index 9837db2..5a5e613 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java @@ -10,6 +10,7 @@ import nl.healthri.fdp.uploadschema.dto.response.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.dto.response.auth.LoginResponse; import nl.healthri.fdp.uploadschema.integrations.FdpClientInterface; +import nl.healthri.fdp.uploadschema.integrations.exceptions.FdpClientException; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; import nl.healthri.fdp.uploadschema.dto.response.Resource.ResourceResponse; import org.slf4j.Logger; @@ -31,42 +32,41 @@ public FdpService(FdpClientInterface fdpClient) { this.fdpClient = fdpClient; } - public void authenticate(String username, String password){ + public void authenticate(String username, String password) throws FdpClientException { LoginRequest loginRequest = new LoginRequest(username, password); LoginResponse loginResponse = fdpClient.getAuthToken(loginRequest); - fdpClient.setAuthToken(loginResponse); } - public List getAllSchemas() { + public List getAllSchemas() throws FdpClientException{ return fdpClient.fetchSchemas(); } - public void createSchema(ShapeTask task){ - List schemaDataResponseList = getAllSchemas(); + public void createSchema(ShapeTask task) throws FdpClientException { + List schemaDataResponseList = getAllSchemas(); - Map schemaInfoMap = new HashMap<>(); - for(SchemaDataResponse schemaDataResponse : schemaDataResponseList) { - Version version = new Version(schemaDataResponse.latest().version()); - SchemaInfo schemaInfo = new SchemaInfo(version, schemaDataResponse.uuid(), schemaDataResponse.latest().definition()); - schemaInfoMap.put(schemaDataResponse.name(), schemaInfo); - } + Map schemaInfoMap = new HashMap<>(); + for(SchemaDataResponse schemaDataResponse : schemaDataResponseList) { + Version version = new Version(schemaDataResponse.latest().version()); + SchemaInfo schemaInfo = new SchemaInfo(version, schemaDataResponse.uuid(), schemaDataResponse.latest().definition()); + schemaInfoMap.put(schemaDataResponse.name(), schemaInfo); + } - UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( - task.shape, - task.description(), false, - task.model, - task.getParentUID(schemaInfoMap), - task.shape, - task.url()); + UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( + task.shape, + task.description(), false, + task.model, + task.getParentUID(schemaInfoMap), + task.shape, + task.url()); - ResourceResponse resourceResponse = fdpClient.insertSchema(task, updateSchemaRequest); - task.uuid = resourceResponse.uuid(); + ResourceResponse resourceResponse = fdpClient.insertSchema(task, updateSchemaRequest); + task.uuid = resourceResponse.uuid(); } - public void updateSchema(ShapeTask task){ + public void updateSchema(ShapeTask task) throws FdpClientException { List schemaDataResponseList = getAllSchemas(); Map schemaInfoMap = new HashMap<>(); @@ -87,17 +87,17 @@ public void updateSchema(ShapeTask task){ fdpClient.updateSchema(task, updateSchemaRequest); } - public void releaseSchema(ShapeTask task){ + public void releaseSchema(ShapeTask task) throws FdpClientException{ ReleaseSchemaRequest releaseSchemaRequest = ReleaseSchemaRequest.of(task.shape, false, task.version); fdpClient.releaseSchema(task, releaseSchemaRequest); } - public List getAllResources() { + public List getAllResources() throws FdpClientException{ return fdpClient.fetchResources(); } - public void createResource(ResourceTask task){ + public void createResource(ResourceTask task) throws FdpClientException{ ResourceRequest resourceRequest = new ResourceRequest( task.resource, task.url(), @@ -110,7 +110,7 @@ public void createResource(ResourceTask task){ task.UUID = resourceResponse.uuid(); } - public void updateResource(ResourceTask task){ + public void updateResource(ResourceTask task) throws FdpClientException{ ResourceResponse resourceResponse = fdpClient.fetchResource(task.UUID); if (resourceResponse.children().stream().anyMatch(c -> c.resourceDefinitionUuid().equals(task.childUUuid))) { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index a5919bf..75b19c0 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -6,8 +6,6 @@ import nl.healthri.fdp.uploadschema.utils.Properties; import nl.healthri.fdp.uploadschema.utils.ResourceInfo; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.util.List; @@ -18,10 +16,8 @@ @Service public class ResourceTaskService implements ResourceTaskServiceInterface { - public FdpService fdpService; - public Properties properties; - - private static final Logger logger = LoggerFactory.getLogger(ResourceTaskService.class); + public final FdpService fdpService; + public final Properties properties; public ResourceTaskService(FdpService fdpService, Properties properties) { this.fdpService = fdpService; @@ -31,7 +27,6 @@ public ResourceTaskService(FdpService fdpService, Properties properties) { public List createTasks() { List resourceResponseList = this.fdpService.getAllResources(); Map resourceInfoMap = createResourceInfoMap(resourceResponseList); - List schemaDataResponseList = this.fdpService.getAllSchemas(); Map schemaInfoMap = createSchemaInfoMap(schemaDataResponseList); From c949faef357b9c8d5310ec3501ac48126573aae7 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Fri, 16 Jan 2026 12:19:42 +0100 Subject: [PATCH 46/51] refactor: merge with feature/clean-up-tasks --- .../nl/healthri/fdp/uploadschema/integrations/FdpClient.java | 1 + .../fdp/uploadschema/integrations/FdpClientInterface.java | 1 + 2 files changed, 2 insertions(+) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java index 8ddd61a..a928c4a 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java @@ -13,6 +13,7 @@ import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.dto.auth.LoginResponse; +import nl.healthri.fdp.uploadschema.integrations.exceptions.FdpClientException; import nl.healthri.fdp.uploadschema.utils.HttpRequestUtils; import org.apache.http.HttpHeaders; diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java index 1cfdc63..0cca0a5 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java @@ -11,6 +11,7 @@ import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; import nl.healthri.fdp.uploadschema.dto.auth.LoginResponse; import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.integrations.exceptions.FdpClientException; import java.util.List; From 7f3d436e20db33b9c62ecbe2e342760f4b6bde10 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Fri, 16 Jan 2026 12:59:53 +0100 Subject: [PATCH 47/51] refactor: improve exception handling for updating and getting settings --- .../fdp/uploadschema/integrations/FdpClient.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java index a928c4a..25a5e3d 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java @@ -392,8 +392,11 @@ public SettingsResponse getSettings() { // Maps response body to object return objectMapper.readValue(response.body(), SettingsResponse.class); - } catch (Exception e) { - throw new RuntimeException(e); + } catch (IOException | URISyntaxException e) { + throw new FdpClientException("Failed to get FDP settings", e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new FdpClientException("Get settings was interrupted", e); } } @@ -422,8 +425,11 @@ public void updateSettings(Settings settings) { // Handle each response based on Fair Data Point (FDP) Swagger documentation. HttpRequestUtils.handleResponseStatus(response); - } catch (Exception e) { - throw new RuntimeException(e); + } catch (IOException | URISyntaxException e) { + throw new FdpClientException("Failed to update settings", e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new FdpClientException("Update settings was interrupted", e); } } From 035f335588412e9067cd0cfa2a46da2e56333ff2 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Mon, 19 Jan 2026 14:43:28 +0100 Subject: [PATCH 48/51] refactor: add "Dto" to class and filename of dto objects and removed unused dtos --- .../dto/Resource/ResourceRequest.java | 17 --------- .../dto/Resource/UpdateResourceResponse.java | 21 ----------- .../dto/Schema/UpdateSchemaResponse.java | 17 --------- .../uploadschema/dto/auth/LoginRequest.java | 5 --- .../dto/auth/LoginRequestDto.java | 5 +++ ...ginResponse.java => LoginResponseDto.java} | 2 +- .../dto/resource/ResourceRequestDto.java | 17 +++++++++ .../ResourceResponseDto.java} | 4 +- .../ReleaseSchemaRequestDto.java} | 8 ++-- .../SchemaDataResponseDto.java} | 4 +- .../UpdateSchemaRequestDto.java} | 4 +- .../dto/settings/SettingsRequestDto.java | 37 +++++++++++++++++++ .../SettingsResponseDto.java} | 10 ++++- 13 files changed, 78 insertions(+), 73 deletions(-) delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/ResourceRequest.java delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/UpdateResourceResponse.java delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/UpdateSchemaResponse.java delete mode 100644 src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginRequest.java create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginRequestDto.java rename src/main/java/nl/healthri/fdp/uploadschema/dto/auth/{LoginResponse.java => LoginResponseDto.java} (72%) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/dto/resource/ResourceRequestDto.java rename src/main/java/nl/healthri/fdp/uploadschema/dto/{Resource/ResourceResponse.java => resource/ResourceResponseDto.java} (91%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/{Schema/ReleaseSchemaRequest.java => schema/ReleaseSchemaRequestDto.java} (53%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/{Schema/SchemaDataResponse.java => schema/SchemaDataResponseDto.java} (90%) rename src/main/java/nl/healthri/fdp/uploadschema/dto/{Schema/UpdateSchemaRequest.java => schema/UpdateSchemaRequestDto.java} (74%) create mode 100644 src/main/java/nl/healthri/fdp/uploadschema/dto/settings/SettingsRequestDto.java rename src/main/java/nl/healthri/fdp/uploadschema/dto/{Settings/SettingsResponse.java => settings/SettingsResponseDto.java} (85%) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/ResourceRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/ResourceRequest.java deleted file mode 100644 index cbe29cd..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/ResourceRequest.java +++ /dev/null @@ -1,17 +0,0 @@ -package nl.healthri.fdp.uploadschema.dto.Resource; - -import java.util.ArrayList; - -public record ResourceRequest(String name, - String urlPrefix, - ArrayList metadataSchemaUuids, - ArrayList targetClassUris, - ArrayList children, - ArrayList externalLinks) { - - public record ResourceChild(String UUID) { - } - - public record ResourceLink(String title, String propertyUri) { - } -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/UpdateResourceResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/UpdateResourceResponse.java deleted file mode 100644 index 78d827a..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/UpdateResourceResponse.java +++ /dev/null @@ -1,21 +0,0 @@ -package nl.healthri.fdp.uploadschema.dto.Resource; - -import nl.healthri.fdp.uploadschema.dto.Resource.ResourceRequest; - -import java.util.ArrayList; - -public record UpdateResourceResponse(String uuid, - String name, - String urlPrefix, - ArrayList metadataSchemaUuids, - ArrayList targetClassUris, - ArrayList children, - ArrayList externalLinks) { - - public record ResourceChild(String UUID) { - } - - public record ResourceLink(String title, String propertyUri) { - } - -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/UpdateSchemaResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/UpdateSchemaResponse.java deleted file mode 100644 index 3be9a63..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/UpdateSchemaResponse.java +++ /dev/null @@ -1,17 +0,0 @@ -package nl.healthri.fdp.uploadschema.dto.Schema; - -import java.util.HashSet; - -public record UpdateSchemaResponse( - String uuid, - String name, - String description, - boolean abstractSchema, - String definition, - HashSet extendsSchemaUuids, - String suggestedResourceName, - String suggestedUrlPrefix, - String lastVersion -) { - -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginRequest.java deleted file mode 100644 index e479182..0000000 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginRequest.java +++ /dev/null @@ -1,5 +0,0 @@ -package nl.healthri.fdp.uploadschema.dto.auth; - -public record LoginRequest(String email, - String password) { -} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginRequestDto.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginRequestDto.java new file mode 100644 index 0000000..7e9e331 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginRequestDto.java @@ -0,0 +1,5 @@ +package nl.healthri.fdp.uploadschema.dto.auth; + +public record LoginRequestDto(String email, + String password) { +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginResponseDto.java similarity index 72% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginResponseDto.java index 294f8f0..0f948fd 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/auth/LoginResponseDto.java @@ -1,6 +1,6 @@ package nl.healthri.fdp.uploadschema.dto.auth; -public record LoginResponse(String token) { +public record LoginResponseDto(String token) { public String asHeaderString() { return "Bearer " + token; } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/resource/ResourceRequestDto.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/resource/ResourceRequestDto.java new file mode 100644 index 0000000..0efc488 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/resource/ResourceRequestDto.java @@ -0,0 +1,17 @@ +package nl.healthri.fdp.uploadschema.dto.resource; + +import java.util.ArrayList; + +public record ResourceRequestDto(String name, + String urlPrefix, + ArrayList metadataSchemaUuids, + ArrayList targetClassUris, + ArrayList children, + ArrayList externalLinks) { + + public record ResourceChild(String UUID) { + } + + public record ResourceLink(String title, String propertyUri) { + } +} diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/ResourceResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/resource/ResourceResponseDto.java similarity index 91% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/ResourceResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/resource/ResourceResponseDto.java index fa90b9b..87b1bfd 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/Resource/ResourceResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/resource/ResourceResponseDto.java @@ -1,11 +1,11 @@ -package nl.healthri.fdp.uploadschema.dto.Resource; +package nl.healthri.fdp.uploadschema.dto.resource; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.util.ArrayList; @JsonIgnoreProperties(ignoreUnknown = true) // Description, abstractschema, definition are ignored. -public record ResourceResponse( +public record ResourceResponseDto( String uuid, String name, String urlPrefix, diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/ReleaseSchemaRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/schema/ReleaseSchemaRequestDto.java similarity index 53% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/ReleaseSchemaRequest.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/schema/ReleaseSchemaRequestDto.java index ffa3cb9..ce253b0 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/ReleaseSchemaRequest.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/schema/ReleaseSchemaRequestDto.java @@ -1,10 +1,10 @@ -package nl.healthri.fdp.uploadschema.dto.Schema; +package nl.healthri.fdp.uploadschema.dto.schema; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import nl.healthri.fdp.uploadschema.domain.Version; -public record ReleaseSchemaRequest( +public record ReleaseSchemaRequestDto( @JsonProperty("description") String resourceName, boolean published, @@ -14,7 +14,7 @@ public record ReleaseSchemaRequest( String patch) { @JsonIgnore - public static ReleaseSchemaRequest of(String resourceName, boolean published, Version v) { - return new ReleaseSchemaRequest(resourceName, published, v.toString(), "" + v.major(), "" + v.minor(), "" + v.patch()); + public static ReleaseSchemaRequestDto of(String resourceName, boolean published, Version v) { + return new ReleaseSchemaRequestDto(resourceName, published, v.toString(), "" + v.major(), "" + v.minor(), "" + v.patch()); } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/SchemaDataResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/schema/SchemaDataResponseDto.java similarity index 90% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/SchemaDataResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/schema/SchemaDataResponseDto.java index 9f6164a..6f35960 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/SchemaDataResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/schema/SchemaDataResponseDto.java @@ -1,8 +1,8 @@ -package nl.healthri.fdp.uploadschema.dto.Schema; +package nl.healthri.fdp.uploadschema.dto.schema; import java.util.ArrayList; -public record SchemaDataResponse( +public record SchemaDataResponseDto( String uuid, String name, Latest latest, diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/UpdateSchemaRequest.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/schema/UpdateSchemaRequestDto.java similarity index 74% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/UpdateSchemaRequest.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/schema/UpdateSchemaRequestDto.java index c9d8fab..6b441f3 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/Schema/UpdateSchemaRequest.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/schema/UpdateSchemaRequestDto.java @@ -1,8 +1,8 @@ -package nl.healthri.fdp.uploadschema.dto.Schema; +package nl.healthri.fdp.uploadschema.dto.schema; import java.util.Set; -public record UpdateSchemaRequest( +public record UpdateSchemaRequestDto( String name, String description, boolean abstractSchema, diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/settings/SettingsRequestDto.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/settings/SettingsRequestDto.java new file mode 100644 index 0000000..17fa6c5 --- /dev/null +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/settings/SettingsRequestDto.java @@ -0,0 +1,37 @@ +package nl.healthri.fdp.uploadschema.dto.settings; + +import com.fasterxml.jackson.databind.ObjectMapper; +import nl.healthri.fdp.uploadschema.config.fdp.Settings; + +import java.util.List; + +public record SettingsRequestDto( + String clientUrl, + String persistentUrl, + String appTitle, + String appSubtitle, + String appTitleFromConfig, + String appSubtitleFromConfig, + List metadataMetrics, + Ping ping, + Repository repository, + Search search, + Forms forms +) { + public record MetadataMetric(String metricUri, String resourceUri) {} + public record Ping(boolean enabled, List endpoints, List endpointsFromConfig, String interval) {} + public record Repository(String type) {} + public record Search(List filters) {} + public record Forms(Autocomplete autocomplete) { + public record Autocomplete(boolean searchNamespace, List sources) { + public record Source(String rdfType, String sparqlEndpoint, String sparqlQuery) {} + } + } + + public static SettingsRequestDto convertToDto(Settings settings) { + ObjectMapper mapper = new ObjectMapper(); + return mapper.convertValue(settings, SettingsRequestDto.class); + } +} + + diff --git a/src/main/java/nl/healthri/fdp/uploadschema/dto/Settings/SettingsResponse.java b/src/main/java/nl/healthri/fdp/uploadschema/dto/settings/SettingsResponseDto.java similarity index 85% rename from src/main/java/nl/healthri/fdp/uploadschema/dto/Settings/SettingsResponse.java rename to src/main/java/nl/healthri/fdp/uploadschema/dto/settings/SettingsResponseDto.java index 62abcd2..69e67ed 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/dto/Settings/SettingsResponse.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/dto/settings/SettingsResponseDto.java @@ -1,8 +1,11 @@ -package nl.healthri.fdp.uploadschema.dto.Settings; +package nl.healthri.fdp.uploadschema.dto.settings; + +import com.fasterxml.jackson.databind.ObjectMapper; +import nl.healthri.fdp.uploadschema.config.fdp.Settings; import java.util.List; -public record SettingsResponse( +public record SettingsResponseDto( String clientUrl, String persistentUrl, String appTitle, @@ -49,4 +52,7 @@ public record Source( ) {} } } + } + + From 0577dfd3506e848ae228a15c4f77cd59e819fa31 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Mon, 19 Jan 2026 14:46:42 +0100 Subject: [PATCH 49/51] refactor: add "Dto" to class and filename of dto objects. --- .../uploadschema/integrations/FdpClient.java | 58 ++++++------- .../integrations/FdpClientInterface.java | 42 +++++----- .../services/FdpServiceInterface.java | 8 +- .../services/ResourceTaskService.java | 15 ++-- .../services/ShapeTaskService.java | 8 +- .../fdp/uploadschema/utils/ResourceInfo.java | 6 +- .../fdp/uploadschema/utils/SchemaInfo.java | 6 +- .../services/ResourceTaskServiceTest.java | 83 +++++++++---------- .../services/ShapeTaskServiceTest.java | 14 ++-- 9 files changed, 114 insertions(+), 126 deletions(-) diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java index 25a5e3d..376b4f0 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClient.java @@ -2,17 +2,17 @@ import com.fasterxml.jackson.databind.ObjectMapper; -import nl.healthri.fdp.uploadschema.config.fdp.Settings; import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; -import nl.healthri.fdp.uploadschema.dto.Resource.ResourceRequest; -import nl.healthri.fdp.uploadschema.dto.Schema.ReleaseSchemaRequest; -import nl.healthri.fdp.uploadschema.dto.Schema.UpdateSchemaRequest; -import nl.healthri.fdp.uploadschema.dto.Settings.SettingsResponse; -import nl.healthri.fdp.uploadschema.dto.auth.LoginRequest; -import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; -import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.dto.auth.LoginResponse; +import nl.healthri.fdp.uploadschema.dto.resource.ResourceRequestDto; +import nl.healthri.fdp.uploadschema.dto.schema.ReleaseSchemaRequestDto; +import nl.healthri.fdp.uploadschema.dto.schema.UpdateSchemaRequestDto; +import nl.healthri.fdp.uploadschema.dto.settings.SettingsRequestDto; +import nl.healthri.fdp.uploadschema.dto.settings.SettingsResponseDto; +import nl.healthri.fdp.uploadschema.dto.auth.LoginRequestDto; +import nl.healthri.fdp.uploadschema.dto.resource.ResourceResponseDto; +import nl.healthri.fdp.uploadschema.dto.schema.SchemaDataResponseDto; +import nl.healthri.fdp.uploadschema.dto.auth.LoginResponseDto; import nl.healthri.fdp.uploadschema.integrations.exceptions.FdpClientException; import nl.healthri.fdp.uploadschema.utils.HttpRequestUtils; @@ -45,7 +45,7 @@ public FdpClient(HttpClient client, URI hostname, ObjectMapper objectMapper) { this.objectMapper = Objects.requireNonNull(objectMapper, "ObjectMapper must not be null"); } - public void setAuthToken(LoginResponse loginResponse) { + public void setAuthToken(LoginResponseDto loginResponse) { this.authToken = loginResponse.asHeaderString(); } @@ -55,7 +55,7 @@ private void isAuthenticated() { } } - public LoginResponse getAuthToken(LoginRequest loginRequest) { + public LoginResponseDto getAuthToken(LoginRequestDto loginRequest) { logger.info("Connecting to FDP at {} as {} ", hostname, loginRequest.email()); try { @@ -80,7 +80,7 @@ public LoginResponse getAuthToken(LoginRequest loginRequest) { HttpRequestUtils.handleResponseStatus(response); // Maps response body to object - return this.objectMapper.readValue(response.body(), LoginResponse.class); + return this.objectMapper.readValue(response.body(), LoginResponseDto.class); } catch (IOException | URISyntaxException e) { throw new FdpClientException("Failed to reach FDP during authentication", e); @@ -90,7 +90,7 @@ public LoginResponse getAuthToken(LoginRequest loginRequest) { } } - public List fetchSchemas() { + public List fetchSchemas() { logger.info("Fetching metadata schemas from FDP"); try { @@ -113,7 +113,7 @@ public List fetchSchemas() { HttpRequestUtils.handleResponseStatus(response); // Maps response body to object - return List.of(objectMapper.readValue(response.body(), SchemaDataResponse[].class)); + return List.of(objectMapper.readValue(response.body(), SchemaDataResponseDto[].class)); } catch (IOException | URISyntaxException e) { throw new FdpClientException("Failed to reach FDP while fetching schemas", e); @@ -127,7 +127,7 @@ public List fetchSchemas() { * @param task task, with info about the shape to create, * when the shapes are created it will update this parameter by setting the UUID! */ - public ResourceResponse insertSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest) { + public ResourceResponseDto insertSchema(ShapeTask task, UpdateSchemaRequestDto updateSchemaRequest) { logger.info("Inserting {} schema into FDP", task.shape); try { @@ -154,7 +154,7 @@ public ResourceResponse insertSchema(ShapeTask task, UpdateSchemaRequest updateS HttpRequestUtils.handleResponseStatus(response); // Maps response body to object - return objectMapper.readValue(response.body(), ResourceResponse.class); + return objectMapper.readValue(response.body(), ResourceResponseDto.class); } catch (IOException | URISyntaxException e) { throw new FdpClientException("Failed to reach FDP while inserting schema for " + task.shape, e); } catch (InterruptedException e) { @@ -166,7 +166,7 @@ public ResourceResponse insertSchema(ShapeTask task, UpdateSchemaRequest updateS - public void updateSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest) { + public void updateSchema(ShapeTask task, UpdateSchemaRequestDto updateSchemaRequest) { logger.info("Updating shape {} in FDP", task.shape); try { @@ -199,7 +199,7 @@ public void updateSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest } } - public void releaseSchema(ShapeTask task, ReleaseSchemaRequest releaseSchemaRequest) { + public void releaseSchema(ShapeTask task, ReleaseSchemaRequestDto releaseSchemaRequest) { logger.info("Releasing {} into FDP", task.shape); try { @@ -233,7 +233,7 @@ public void releaseSchema(ShapeTask task, ReleaseSchemaRequest releaseSchemaRequ } } - public List fetchResources() { + public List fetchResources() { logger.info("Fetching resources from fdp"); try { @@ -256,7 +256,7 @@ public List fetchResources() { HttpRequestUtils.handleResponseStatus(response); // Map response to body - return List.of(objectMapper.readValue(response.body(), ResourceResponse[].class)); + return List.of(objectMapper.readValue(response.body(), ResourceResponseDto[].class)); } catch (IOException | URISyntaxException e) { throw new FdpClientException("Failed to reach FDP while fetching resources", e); } catch (InterruptedException e) { @@ -265,7 +265,7 @@ public List fetchResources() { } } - public ResourceResponse fetchResource(String resourceId){ + public ResourceResponseDto fetchResource(String resourceId){ logger.info("fetching resource {} from FDP", resourceId); try { @@ -288,7 +288,7 @@ public ResourceResponse fetchResource(String resourceId){ HttpRequestUtils.handleResponseStatus(response); // Maps response body to object - return objectMapper.readValue(response.body(), ResourceResponse.class); + return objectMapper.readValue(response.body(), ResourceResponseDto.class); } catch (IOException | URISyntaxException e) { throw new FdpClientException("Failed to reach FDP while fetching resource " + resourceId, e); } catch (InterruptedException e) { @@ -297,7 +297,7 @@ public ResourceResponse fetchResource(String resourceId){ } } - public ResourceResponse insertResource(ResourceTask task, ResourceRequest resourceRequest) { + public ResourceResponseDto insertResource(ResourceTask task, ResourceRequestDto resourceRequest) { logger.info("Inserting {} resources into FDP", task.resource); try { @@ -325,7 +325,7 @@ public ResourceResponse insertResource(ResourceTask task, ResourceRequest resour HttpRequestUtils.handleResponseStatus(response); // Maps response body to object - return objectMapper.readValue(response.body(), ResourceResponse.class); + return objectMapper.readValue(response.body(), ResourceResponseDto.class); } catch (IOException | URISyntaxException e) { throw new FdpClientException("Failed to reach FDP while inserting resource " + task.resource, e); } catch (InterruptedException e) { @@ -334,7 +334,7 @@ public ResourceResponse insertResource(ResourceTask task, ResourceRequest resour } } - public void updateResource(ResourceTask task, ResourceResponse resourceResponse) { + public void updateResource(ResourceTask task, ResourceResponseDto resourceResponse) { logger.info("updating resource {} in FDP", task.resource); try { @@ -368,7 +368,7 @@ public void updateResource(ResourceTask task, ResourceResponse resourceResponse) } - public SettingsResponse getSettings() { + public SettingsResponseDto getSettings() { logger.info("getting settings from FDP"); try { @@ -391,7 +391,7 @@ public SettingsResponse getSettings() { HttpRequestUtils.handleResponseStatus(response); // Maps response body to object - return objectMapper.readValue(response.body(), SettingsResponse.class); + return objectMapper.readValue(response.body(), SettingsResponseDto.class); } catch (IOException | URISyntaxException e) { throw new FdpClientException("Failed to get FDP settings", e); } catch (InterruptedException e) { @@ -400,7 +400,7 @@ public SettingsResponse getSettings() { } } - public void updateSettings(Settings settings) { + public void updateSettings(SettingsRequestDto settingsRequestDto) { logger.info("updating settings in FDP"); try { @@ -409,7 +409,7 @@ public void updateSettings(Settings settings) { URI uri = new URI(this.hostname + "/settings"); HttpRequest.BodyPublisher body = HttpRequest.BodyPublishers.ofString( - this.objectMapper.writeValueAsString(settings) + this.objectMapper.writeValueAsString(settingsRequestDto) ); HttpRequest request = HttpRequest.newBuilder() diff --git a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java index 0cca0a5..67d45b1 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/integrations/FdpClientInterface.java @@ -1,34 +1,34 @@ package nl.healthri.fdp.uploadschema.integrations; -import nl.healthri.fdp.uploadschema.config.fdp.Settings; import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; -import nl.healthri.fdp.uploadschema.dto.Resource.ResourceRequest; -import nl.healthri.fdp.uploadschema.dto.Schema.ReleaseSchemaRequest; -import nl.healthri.fdp.uploadschema.dto.Schema.UpdateSchemaRequest; -import nl.healthri.fdp.uploadschema.dto.Settings.SettingsResponse; -import nl.healthri.fdp.uploadschema.dto.auth.LoginRequest; -import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.dto.auth.LoginResponse; -import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.resource.ResourceRequestDto; +import nl.healthri.fdp.uploadschema.dto.schema.ReleaseSchemaRequestDto; +import nl.healthri.fdp.uploadschema.dto.schema.UpdateSchemaRequestDto; +import nl.healthri.fdp.uploadschema.dto.settings.SettingsRequestDto; +import nl.healthri.fdp.uploadschema.dto.settings.SettingsResponseDto; +import nl.healthri.fdp.uploadschema.dto.auth.LoginRequestDto; +import nl.healthri.fdp.uploadschema.dto.schema.SchemaDataResponseDto; +import nl.healthri.fdp.uploadschema.dto.auth.LoginResponseDto; +import nl.healthri.fdp.uploadschema.dto.resource.ResourceResponseDto; import nl.healthri.fdp.uploadschema.integrations.exceptions.FdpClientException; import java.util.List; public interface FdpClientInterface { - void setAuthToken(LoginResponse loginResponse); - LoginResponse getAuthToken(LoginRequest loginRequest) throws FdpClientException; + void setAuthToken(LoginResponseDto loginResponse); + LoginResponseDto getAuthToken(LoginRequestDto loginRequest) throws FdpClientException; - List fetchSchemas() throws FdpClientException; - ResourceResponse insertSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest) throws FdpClientException; - void updateSchema(ShapeTask task, UpdateSchemaRequest updateSchemaRequest) throws FdpClientException; - void releaseSchema(ShapeTask task, ReleaseSchemaRequest releaseSchemaRequest) throws FdpClientException; + List fetchSchemas() throws FdpClientException; + ResourceResponseDto insertSchema(ShapeTask task, UpdateSchemaRequestDto updateSchemaRequest) throws FdpClientException; + void updateSchema(ShapeTask task, UpdateSchemaRequestDto updateSchemaRequest) throws FdpClientException; + void releaseSchema(ShapeTask task, ReleaseSchemaRequestDto releaseSchemaRequest) throws FdpClientException; - List fetchResources() throws FdpClientException; - ResourceResponse fetchResource(String resourceId) throws FdpClientException; - ResourceResponse insertResource(ResourceTask task, ResourceRequest resourceRequest) throws FdpClientException; - void updateResource(ResourceTask task, ResourceResponse resourceResponse) throws FdpClientException; + List fetchResources() throws FdpClientException; + ResourceResponseDto fetchResource(String resourceId) throws FdpClientException; + ResourceResponseDto insertResource(ResourceTask task, ResourceRequestDto resourceRequest) throws FdpClientException; + void updateResource(ResourceTask task, ResourceResponseDto resourceResponse) throws FdpClientException; - SettingsResponse getSettings(); - void updateSettings(Settings settings); + SettingsResponseDto getSettings() throws FdpClientException; + void updateSettings(SettingsRequestDto settingsRequestDto) throws FdpClientException; } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/FdpServiceInterface.java b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpServiceInterface.java index 5e65c71..c8ef0a1 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/FdpServiceInterface.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpServiceInterface.java @@ -3,21 +3,21 @@ import nl.healthri.fdp.uploadschema.config.fdp.Settings; import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; -import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.schema.SchemaDataResponseDto; +import nl.healthri.fdp.uploadschema.dto.resource.ResourceResponseDto; import java.util.List; public interface FdpServiceInterface { void authenticate(String username, String password); - List getAllSchemas(); + List getAllSchemas(); void createSchema(ShapeTask task); void updateSchema(ShapeTask task); void releaseSchema(ShapeTask task); - List getAllResources(); + List getAllResources(); void createResource(ResourceTask task); void updateResource(ResourceTask task); diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java index 7764227..4d69ef0 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ResourceTaskService.java @@ -1,13 +1,11 @@ package nl.healthri.fdp.uploadschema.services; import nl.healthri.fdp.uploadschema.domain.ResourceTask; -import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; -import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.resource.ResourceResponseDto; +import nl.healthri.fdp.uploadschema.dto.schema.SchemaDataResponseDto; import nl.healthri.fdp.uploadschema.config.fdp.Properties; import nl.healthri.fdp.uploadschema.utils.ResourceInfo; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.util.List; @@ -21,9 +19,6 @@ public class ResourceTaskService implements ResourceTaskServiceInterface { public FdpServiceInterface fdpService; public Properties properties; - - private static final Logger logger = LoggerFactory.getLogger(ResourceTaskService.class); - public ResourceTaskService(FdpServiceInterface fdpService, Properties properties) { this.fdpService = fdpService; this.properties = properties; @@ -43,10 +38,10 @@ protected record ParentResourceData( public List createTasks() { - List fdpResourceResponseList = this.fdpService.getAllResources(); + List fdpResourceResponseList = this.fdpService.getAllResources(); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); - List fdpSchemaDataResponseList = this.fdpService.getAllSchemas(); + List fdpSchemaDataResponseList = this.fdpService.getAllSchemas(); Map fdpSchemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); return properties.resources.entrySet().stream().map(propertyResource -> { @@ -66,7 +61,7 @@ public List createTasks() { } public List createParentTasks() { - List fdpResourceResponseList = this.fdpService.getAllResources(); + List fdpResourceResponseList = this.fdpService.getAllResources(); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); return this.properties.resources.entrySet().stream().map(propertyResource -> { diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java index 93e28b9..44749af 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/ShapeTaskService.java @@ -3,13 +3,11 @@ import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.domain.ShapeTask; import nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus; -import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.schema.SchemaDataResponseDto; import nl.healthri.fdp.uploadschema.utils.*; import nl.healthri.fdp.uploadschema.config.fdp.Properties; import org.eclipse.rdf4j.model.Model; import org.eclipse.rdf4j.model.util.Models; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.net.URI; @@ -24,8 +22,6 @@ public class ShapeTaskService implements ShapeTaskServiceInterface { public FileHandler fileHandler; public Properties properties; - private static final Logger logger = LoggerFactory.getLogger(ShapeTaskService.class); - public ShapeTaskService(FdpServiceInterface fdpServiceInterface, FileHandler fileHandler, Properties properties) { this.fdpService = fdpServiceInterface; this.fileHandler = fileHandler; @@ -34,7 +30,7 @@ public ShapeTaskService(FdpServiceInterface fdpServiceInterface, FileHandler fil public List createTasks() { Map> files = this.properties.getFiles(); - List schemaDataResponseList = this.fdpService.getAllSchemas(); + List schemaDataResponseList = this.fdpService.getAllSchemas(); Map shapesOnFdp = createSchemaInfoMap(schemaDataResponseList); //list of the task we have to do for insert/updating shacls diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java index d251b46..0b160fa 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/ResourceInfo.java @@ -1,15 +1,15 @@ package nl.healthri.fdp.uploadschema.utils; -import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.resource.ResourceResponseDto; import java.util.HashMap; import java.util.List; import java.util.Map; public record ResourceInfo(String name, String uuid) { - public static Map createResourceInfoMap(List resourceResponseList){ + public static Map createResourceInfoMap(List resourceResponseList){ Map fdpResourceMap = new HashMap<>(); - for(ResourceResponse resourceResponse : resourceResponseList) { + for(ResourceResponseDto resourceResponse : resourceResponseList) { ResourceInfo resourceInfo = new ResourceInfo(resourceResponse.name(), resourceResponse.uuid()); fdpResourceMap.put(resourceResponse.name(), resourceInfo); } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java b/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java index ba372a7..a97afea 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/utils/SchemaInfo.java @@ -1,16 +1,16 @@ package nl.healthri.fdp.uploadschema.utils; import nl.healthri.fdp.uploadschema.domain.Version; -import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.schema.SchemaDataResponseDto; import java.util.HashMap; import java.util.List; import java.util.Map; public record SchemaInfo(Version version, String uuid, String definition) { - public static Map createSchemaInfoMap(List schemaDataResponseList) { + public static Map createSchemaInfoMap(List schemaDataResponseList) { Map schemaInfoMap = new HashMap<>(); - for (SchemaDataResponse schemaDataResponse : schemaDataResponseList) { + for (SchemaDataResponseDto schemaDataResponse : schemaDataResponseList) { Version version = new Version(schemaDataResponse.latest().version()); SchemaInfo schemaInfo = new SchemaInfo( diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java index a06b3a8..b2e24f4 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ResourceTaskServiceTest.java @@ -2,8 +2,8 @@ import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.Version; -import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; -import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.resource.ResourceResponseDto; +import nl.healthri.fdp.uploadschema.dto.schema.SchemaDataResponseDto; import nl.healthri.fdp.uploadschema.config.fdp.Properties; import nl.healthri.fdp.uploadschema.utils.ResourceInfo; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; @@ -72,20 +72,20 @@ private Properties getProperties() { return properties; } - List getResourceResponseList(String name1, String name2, String name3) { + List getResourceResponseList(String name1, String name2, String name3) { return List.of( - new ResourceResponse( + new ResourceResponseDto( "1", name1, null, null, null, null, null ), - new ResourceResponse( + new ResourceResponseDto( "2", name2, null, null, null, null, null ), - new ResourceResponse( + new ResourceResponseDto( "3", name3, null, null, null, null, null @@ -94,25 +94,25 @@ List getResourceResponseList(String name1, String name2, Strin ); } - List getResourceResponseListWithParent(String name1, String name2, String name3, String name4) { + List getResourceResponseListWithParent(String name1, String name2, String name3, String name4) { return List.of( - new ResourceResponse( + new ResourceResponseDto( "1", name1, null, null, null, null, null ), - new ResourceResponse( + new ResourceResponseDto( "2", name2, null, null, null, null, null ), - new ResourceResponse( + new ResourceResponseDto( "3", name3, null, null, null, null, null ), - new ResourceResponse( + new ResourceResponseDto( "4", name4, null, null, null, null, null @@ -120,12 +120,12 @@ List getResourceResponseListWithParent(String name1, String na ); } - List getSchemaDataResponseList(String name1, String name2, String name3) { + List getSchemaDataResponseList(String name1, String name2, String name3) { return List.of( - new SchemaDataResponse( + new SchemaDataResponseDto( "1", name1, - new SchemaDataResponse.Latest( + new SchemaDataResponseDto.Latest( null, new Version(1, 0, 0).toString(), null, @@ -149,10 +149,10 @@ List getSchemaDataResponseList(String name1, String name2, S null, null ), - new SchemaDataResponse( + new SchemaDataResponseDto( "2", name2, - new SchemaDataResponse.Latest( + new SchemaDataResponseDto.Latest( null, new Version(1, 0, 0).toString(), null, @@ -176,10 +176,10 @@ List getSchemaDataResponseList(String name1, String name2, S null, null ), - new SchemaDataResponse( + new SchemaDataResponseDto( "3", name3, - new SchemaDataResponse.Latest( + new SchemaDataResponseDto.Latest( null, new Version(1, 0, 0).toString(), null, @@ -210,13 +210,13 @@ List getSchemaDataResponseList(String name1, String name2, S @Test void PropertyResourceNotFoundInFdpResourceInfoMap_WhenGettingResourceInfo_ResourceDataEmptyIdAndExistsFalse() { // Arrange - List fdpResourceResponseList = getResourceResponseList("resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); + List fdpResourceResponseList = getResourceResponseList("resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); // Act & Assert - this.resourceTaskService.properties.resources.entrySet().forEach(propertyResource -> { + this.resourceTaskService.properties.resources.forEach((key, value) -> { ResourceTaskService.ResourceData resourceData = - this.resourceTaskService.getResourceInfo(propertyResource.getKey(), fdpResourceInfoMap); + this.resourceTaskService.getResourceInfo(key, fdpResourceInfoMap); // Assert assertEquals("", resourceData.resourceUUID()); @@ -227,16 +227,16 @@ void PropertyResourceNotFoundInFdpResourceInfoMap_WhenGettingResourceInfo_Resour @Test void PropertyResourceFoundInFdpResourceInfoMap_WhenGettingResourceInfo_ResourceDataIdIsFdpUuidIdAndExistsTrue() { // Arrange - List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); + List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); // Act & Assert - this.resourceTaskService.properties.resources.entrySet().forEach(propertyResource -> { + this.resourceTaskService.properties.resources.forEach((key, value) -> { ResourceTaskService.ResourceData resourceData = - this.resourceTaskService.getResourceInfo(propertyResource.getKey(), fdpResourceInfoMap); + this.resourceTaskService.getResourceInfo(key, fdpResourceInfoMap); // Assert - String fdpResourceUuid = fdpResourceInfoMap.get(propertyResource.getKey()).uuid(); + String fdpResourceUuid = fdpResourceInfoMap.get(key).uuid(); assertEquals(fdpResourceUuid, resourceData.resourceUUID()); assertTrue(resourceData.exists()); }); @@ -245,15 +245,15 @@ void PropertyResourceFoundInFdpResourceInfoMap_WhenGettingResourceInfo_ResourceD @Test void PropertyResourceNotFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsEmptyId() { // Arrange - List fdpSchemaDataResponseList = getSchemaDataResponseList("resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); + List fdpSchemaDataResponseList = getSchemaDataResponseList("resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); Map fdpSchemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); // Act & Assert - this.resourceTaskService.properties.resources.entrySet().forEach(propertyResource -> { + this.resourceTaskService.properties.resources.forEach((key, value) -> { // Act - String resourceSchemaId = this.resourceTaskService.getSchemaUUID(propertyResource.getKey(), propertyResource.getValue().schema(), fdpSchemaInfoMap); + String resourceSchemaId = this.resourceTaskService.getSchemaUUID(key, value.schema(), fdpSchemaInfoMap); // Assert assertEquals("", resourceSchemaId); @@ -263,21 +263,20 @@ void PropertyResourceNotFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsEmp @Test void PropertyResourceFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsSchemaIdFromFdpSchema() { // Arrange - List fdpSchemaDataResponseList = getSchemaDataResponseList("Distribution", "Dataset Series", "Distribution"); + List fdpSchemaDataResponseList = getSchemaDataResponseList("Distribution", "Dataset Series", "Distribution"); Map fdpSchemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); // Act & Assert - this.resourceTaskService.properties.resources.entrySet().forEach(propertyResource -> { - String propertyResourceName = propertyResource.getKey(); - String propertyResourceSchema = propertyResource.getValue().schema(); + this.resourceTaskService.properties.resources.forEach((propertyResourceName, value) -> { + String propertyResourceSchema = value.schema(); // Act String resourceSchemaId = this.resourceTaskService.getSchemaUUID(propertyResourceName, propertyResourceSchema, fdpSchemaInfoMap); // Assert - String expectedSchemaId = fdpSchemaInfoMap.get(propertyResource.getValue().schema()).uuid(); + String expectedSchemaId = fdpSchemaInfoMap.get(value.schema()).uuid(); assertEquals(expectedSchemaId, resourceSchemaId); }); } @@ -285,7 +284,7 @@ void PropertyResourceFoundInFdpSchemaInfoMap_WhenGettingSchemaUuid_ReturnsSchema @Test void PropertyParentResourceNotFoundInFdpResourceInfoMap_WhenGettingParentResourceInfo_ReturnEmptyParentResourceData(){ // Arrange - List fdpResourceResponseList = getResourceResponseListWithParent("parent-resource-not-in-fdp", "resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); + List fdpResourceResponseList = getResourceResponseListWithParent("parent-resource-not-in-fdp", "resource-not-in-fdp-1", "resource-not-in-fdp-2", "resource-not-in-fdp-3"); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); // Act & Assert @@ -308,7 +307,7 @@ void PropertyParentResourceNotFoundInFdpResourceInfoMap_WhenGettingParentResourc void PropertyParentResourceFoundInFdpResourceInfoMap_WhenGettingParentResourceInfo_ReturnParentResourceDataWithFilledChildInfo(){ // Arrange - List fdpResourceResponseList = getResourceResponseListWithParent("Dataset", "Sample Distribution", "Dataset Series", "Analytics Distribution"); + List fdpResourceResponseList = getResourceResponseListWithParent("Dataset", "Sample Distribution", "Dataset Series", "Analytics Distribution"); Map fdpResourceInfoMap = createResourceInfoMap(fdpResourceResponseList); // Act & Assert @@ -339,11 +338,11 @@ void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTask // Arrange - List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); + List fdpResourceResponseList = getResourceResponseList("Sample Distribution", "Dataset Series", "Analytics Distribution"); Map fdpResourceMap = createResourceInfoMap(fdpResourceResponseList); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); - List fdpSchemaDataResponseList = getSchemaDataResponseList("Distribution", "Dataset Series", "Distribution"); + List fdpSchemaDataResponseList = getSchemaDataResponseList("Distribution", "Dataset Series", "Distribution"); Map schemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); @@ -368,12 +367,10 @@ void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTask @Test void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsTasksThatDoNotExist() { // Arrange - List fdpResourceResponseList = getResourceResponseList("not-in-fdp-1", "not-in-fdp-2", "not-in-fdp-3"); - Map fdpResourceMap = createResourceInfoMap(fdpResourceResponseList); + List fdpResourceResponseList = getResourceResponseList("not-in-fdp-1", "not-in-fdp-2", "not-in-fdp-3"); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); - List fdpSchemaDataResponseList = getSchemaDataResponseList("Distribution", "Dataset Series", "Distribution"); - Map schemaInfoMap = createSchemaInfoMap(fdpSchemaDataResponseList); + List fdpSchemaDataResponseList = getSchemaDataResponseList("Distribution", "Dataset Series", "Distribution"); when(fdpServiceMock.getAllSchemas()).thenReturn(fdpSchemaDataResponseList); // Act @@ -390,7 +387,7 @@ void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingTasks_ReturnsT @Test void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingParentTasks_ReturnsTasksWithFilledChildDataAndExistsIsTrue() { // Arrange - List fdpResourceResponseList = getResourceResponseListWithParent("Dataset", "Sample Distribution", "Dataset Series", "Analytics Distribution"); + List fdpResourceResponseList = getResourceResponseListWithParent("Dataset", "Sample Distribution", "Dataset Series", "Analytics Distribution"); Map resourceInfoMap = createResourceInfoMap(fdpResourceResponseList); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); @@ -417,7 +414,7 @@ void AllPropertyResourcesFoundInFdpResourceInfoMap_WhenCreatingParentTasks_Retur @Test void AllPropertyResourcesNotFoundInFdpResourceInfoMap_WhenCreatingParentTasks_ReturnsTasksWithEmptyChildDataAndExistsIsFalse() { // Arrange - List fdpResourceResponseList = getResourceResponseListWithParent("not-in-fdp-parent", "not-in-fdp-1", "not-in-fdp-2", "not-in-fdp-3"); + List fdpResourceResponseList = getResourceResponseListWithParent("not-in-fdp-parent", "not-in-fdp-1", "not-in-fdp-2", "not-in-fdp-3"); when(fdpServiceMock.getAllResources()).thenReturn(fdpResourceResponseList); // Act diff --git a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java index 92c1d98..c97e4b2 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/services/ShapeTaskServiceTest.java @@ -3,7 +3,7 @@ import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.domain.ShapeTask; import nl.healthri.fdp.uploadschema.domain.enums.ShapeStatus; -import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; +import nl.healthri.fdp.uploadschema.dto.schema.SchemaDataResponseDto; import nl.healthri.fdp.uploadschema.utils.*; import nl.healthri.fdp.uploadschema.config.fdp.Properties; import org.eclipse.rdf4j.model.Model; @@ -113,13 +113,13 @@ void propertiesSchemaTitleFoundInFdpSchemaInfoMap_WhenLookingForTitleKeyValue_Re Model model = newModel(); String ttl = RdfUtils.modelAsTurtleString(model); - SchemaDataResponse.Latest latest = new SchemaDataResponse.Latest( + SchemaDataResponseDto.Latest latest = new SchemaDataResponseDto.Latest( "uuid-latest", "1.0.0", "vUuid", null, schemaTitle, true, false, true, "type", "origin", "imported", ttl, "desc", new ArrayList<>(), new ArrayList<>(), "res", "prefix" ); - SchemaDataResponse fdpSchemaDataResponse = new SchemaDataResponse( + SchemaDataResponseDto fdpSchemaDataResponse = new SchemaDataResponseDto( "uuid-main", schemaTitle, latest, null, new ArrayList<>(), new ArrayList<>(), new ArrayList<>() ); @@ -175,7 +175,7 @@ void NoChangesFound_WhenComparingPropertiesFileWithMatchingFdpShapeFile_ReturnsN Model sameModel = newModel(); String ttlDifferentModel = RdfUtils.modelAsTurtleString(sameModel); - SchemaDataResponse.Latest latest = new SchemaDataResponse.Latest( + SchemaDataResponseDto.Latest latest = new SchemaDataResponseDto.Latest( "uuid-latest", "1.0.0", "versionUuid", @@ -195,7 +195,7 @@ void NoChangesFound_WhenComparingPropertiesFileWithMatchingFdpShapeFile_ReturnsN "urlPrefix" ); - SchemaDataResponse existingResponse = new SchemaDataResponse( + SchemaDataResponseDto existingResponse = new SchemaDataResponseDto( "uuid-main", schemaTitle, latest, @@ -231,7 +231,7 @@ void ChangesFound_WhenComparingPropertiesFileWithMatchingFdpShapeFile_ReturnsNew Model sameModel = newDifferentModel(); String ttlDifferentModel = RdfUtils.modelAsTurtleString(sameModel); - SchemaDataResponse.Latest latest = new SchemaDataResponse.Latest( + SchemaDataResponseDto.Latest latest = new SchemaDataResponseDto.Latest( "uuid-latest", "1.0.0", "versionUuid", @@ -251,7 +251,7 @@ void ChangesFound_WhenComparingPropertiesFileWithMatchingFdpShapeFile_ReturnsNew "urlPrefix" ); - SchemaDataResponse existingResponse = new SchemaDataResponse( + SchemaDataResponseDto existingResponse = new SchemaDataResponseDto( "uuid-main", schemaTitle, latest, From 7dcdbf249c30c35475fb6f8cd3a8e595365397c9 Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Mon, 19 Jan 2026 15:06:11 +0100 Subject: [PATCH 50/51] fix: duplicate autocomplete form sources being saved fixed. Settings pulled from FDP are now used to merge the local settings into. --- FdpSettings.json | 35 ------ pom.xml | 8 +- .../fdp/uploadschema/config/fdp/Settings.java | 101 ++++++------------ .../fdp/uploadschema/services/FdpService.java | 62 ++++++----- .../fdp/uploadschema/config/SettingsTest.java | 75 ++++--------- 5 files changed, 98 insertions(+), 183 deletions(-) diff --git a/FdpSettings.json b/FdpSettings.json index 447cd64..8e30a33 100644 --- a/FdpSettings.json +++ b/FdpSettings.json @@ -1,34 +1,4 @@ { - "clientUrl": "http://localhost", - "persistentUrl": "http://localhost:8080", - "appTitle": null, - "appSubtitle": null, - "appTitleFromConfig": "FAIR Data Point", - "appSubtitleFromConfig": "Metadata for machines", - "metadataMetrics": [ - { - "metricUri": "https://purl.org/fair-metrics/FM_F1A", - "resourceUri": "https://www.ietf.org/rfc/rfc3986.txt" - }, - { - "metricUri": "https://purl.org/fair-metrics/FM_A1.1", - "resourceUri": "https://www.wikidata.org/wiki/Q8777" - } - ], - "ping": { - "enabled": true, - "endpoints": [], - "endpointsFromConfig": [ - "https://home.fairdatapoint.org" - ], - "interval": "PT168H" - }, - "repository": { - "type": "InMemory" - }, - "search": { - "filters": [] - }, "forms": { "autocomplete": { "searchNamespace": true, @@ -52,11 +22,6 @@ "rdfType": "http://purl.org/dc/terms/Concept", "sparqlEndpoint": "https://sparql-test.healthdata.nl/repositories/controlled-vocabularies", "sparqlQuery": "PREFIX skos: \nSELECT ?entity ?entityLabel WHERE {\n GRAPH {\n ?entity skos:prefLabel ?entityLabel\n FILTER ( lang(?entityLabel) = \"en\")\n }\n}" - }, - { - "rdfType": "http://purl.org/dc/terms/Test", - "sparqlEndpoint": "https://sparql-test.healthdata.nl/repositories/test", - "sparqlQuery": "PREFIX skos: \nSELECT ?entity ?entityLabel WHERE {\n GRAPH {\n ?entity skos:prefLabel ?entityLabel\n FILTER ( lang(?entityLabel) = \"en\")\n }\n}" } ] } diff --git a/pom.xml b/pom.xml index b2dac9d..7610b29 100644 --- a/pom.xml +++ b/pom.xml @@ -72,7 +72,7 @@ ch.qos.logback logback-core - 1.5.18 + 1.5.19 ch.qos.logback @@ -147,6 +147,12 @@ 3.5.0 + + org.modelmapper + modelmapper + 3.2.6 + + diff --git a/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java b/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java index 3a7af0e..008d276 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/config/fdp/Settings.java @@ -1,17 +1,17 @@ package nl.healthri.fdp.uploadschema.config.fdp; import com.fasterxml.jackson.databind.ObjectMapper; -import nl.healthri.fdp.uploadschema.dto.Settings.SettingsResponse; +import nl.healthri.fdp.uploadschema.dto.settings.SettingsResponseDto; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; -import static java.util.stream.Collectors.toMap; +import nl.healthri.fdp.uploadschema.config.fdp.Settings.Forms.Autocomplete.Source; public class Settings { private static Settings settings; @@ -28,8 +28,6 @@ public class Settings { public Search search; public Forms forms; - public Settings() {} - public static class MetadataMetric { public String metricUri; public String resourceUri; @@ -62,10 +60,16 @@ public static class Source { public String rdfType; public String sparqlEndpoint; public String sparqlQuery; + + public String getRdfType() { + return rdfType; + } } } } + public Settings() {} + // Always returns the existing settings if already initialized. public static Settings GetSettings(){ if(settings == null){ @@ -89,72 +93,35 @@ public static Settings GetSettings(File file) throws IOException { } - // Merges all data from fdpSettings into Settings instance only adding missing form sources from Settings instance - public Settings Merge(SettingsResponse fdpSettings){ - Settings mergedSettings = settings; - - mergedSettings.clientUrl = fdpSettings.clientUrl(); - mergedSettings.persistentUrl = fdpSettings.persistentUrl(); - mergedSettings.appTitle = fdpSettings.appTitle(); - mergedSettings.appSubtitle = fdpSettings.appSubtitle(); - mergedSettings.appTitleFromConfig = fdpSettings.appTitleFromConfig(); - mergedSettings.appSubtitleFromConfig = fdpSettings.appSubtitleFromConfig(); - mergedSettings.metadataMetrics = fdpSettings.metadataMetrics().stream() - .map(m -> { - MetadataMetric mm = new MetadataMetric(); - mm.metricUri = m.metricUri(); - mm.resourceUri = m.resourceUri(); - return mm; - }).toList(); - - if (mergedSettings.ping == null) mergedSettings.ping = new Ping(); - mergedSettings.ping.enabled = fdpSettings.ping().enabled(); - mergedSettings.ping.endpoints = fdpSettings.ping().endpoints(); - mergedSettings.ping.endpointsFromConfig = fdpSettings.ping().endpointsFromConfig(); - mergedSettings.ping.interval = fdpSettings.ping().interval(); - - if (mergedSettings.repository == null) mergedSettings.repository = new Repository(); - this.repository.type = fdpSettings.repository().type(); - - if (mergedSettings.search == null) mergedSettings.search = new Search(); - mergedSettings.search.filters = fdpSettings.search().filters(); - - if (mergedSettings.forms == null) mergedSettings.forms = new Forms(); - if (mergedSettings.forms.autocomplete == null) mergedSettings.forms.autocomplete = new Forms.Autocomplete(); - - mergedSettings.forms.autocomplete.searchNamespace = - fdpSettings.forms().autocomplete().searchNamespace(); - - List mergedSources = new java.util.ArrayList<>(); - List settingsSources = mergedSettings.forms.autocomplete.sources; - - // Creates map with RdfType as key and the Source as value - // Each source is mapped from SettingsResponse Source to Settings Source. - List fdpSourceList = new ArrayList<>(); - List fdpSources = fdpSettings.forms().autocomplete().sources(); - for (SettingsResponse.Forms.Autocomplete.Source source : fdpSources) { - Forms.Autocomplete.Source src = new Forms.Autocomplete.Source(); - src.rdfType = source.rdfType(); - src.sparqlEndpoint = source.sparqlEndpoint(); - src.sparqlQuery = source.sparqlQuery(); - mergedSettings.forms.autocomplete.sources.add(src); + // Merges missing sources from new settings into current settings + public Settings Merge(Settings newSettings){ + // Early return if new settings are invalid + if (newSettings == null || + newSettings.forms == null || + newSettings.forms.autocomplete == null || + newSettings.forms.autocomplete.sources == null) { + return this; } + List currentSources = this.forms.autocomplete.sources; + List newSources = newSettings.forms.autocomplete.sources; - // Checks if each Source in Settings is already the in mergedSettings resource. - // Adds to mergedSettings resource list if resource is not in merged settings. - if (settingsSources != null) { - for (Forms.Autocomplete.Source source : settingsSources) { - boolean exists = mergedSettings.forms.autocomplete.sources - .stream() - .anyMatch(s -> Objects.equals(s.rdfType, source.rdfType)); + // Collect existing rdfTypes into a Set for simpler lookup + Set existingTypes = currentSources.stream() + .map(Source::getRdfType) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); - if (!exists) { - mergedSettings.forms.autocomplete.sources.add(source); - } - } - } + // Add sources with rdfTypes not located in currentSources + newSources.stream() + .filter(s -> s.getRdfType() != null && !existingTypes.contains(s.getRdfType())) + .forEach(currentSources::add); return this; } + + public static Settings convertToEntity(SettingsResponseDto settingsResponseDTO) { + ObjectMapper mapper = new ObjectMapper(); + return mapper.convertValue(settingsResponseDTO, Settings.class); + } } diff --git a/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java index c24ef1b..cf8a5e5 100644 --- a/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java +++ b/src/main/java/nl/healthri/fdp/uploadschema/services/FdpService.java @@ -4,17 +4,18 @@ import nl.healthri.fdp.uploadschema.domain.Version; import nl.healthri.fdp.uploadschema.domain.ResourceTask; import nl.healthri.fdp.uploadschema.domain.ShapeTask; -import nl.healthri.fdp.uploadschema.dto.Resource.ResourceRequest; -import nl.healthri.fdp.uploadschema.dto.Schema.ReleaseSchemaRequest; -import nl.healthri.fdp.uploadschema.dto.Schema.UpdateSchemaRequest; -import nl.healthri.fdp.uploadschema.dto.Settings.SettingsResponse; -import nl.healthri.fdp.uploadschema.dto.auth.LoginRequest; -import nl.healthri.fdp.uploadschema.dto.Schema.SchemaDataResponse; -import nl.healthri.fdp.uploadschema.dto.auth.LoginResponse; +import nl.healthri.fdp.uploadschema.dto.resource.ResourceRequestDto; +import nl.healthri.fdp.uploadschema.dto.schema.ReleaseSchemaRequestDto; +import nl.healthri.fdp.uploadschema.dto.schema.UpdateSchemaRequestDto; +import nl.healthri.fdp.uploadschema.dto.settings.SettingsRequestDto; +import nl.healthri.fdp.uploadschema.dto.settings.SettingsResponseDto; +import nl.healthri.fdp.uploadschema.dto.auth.LoginRequestDto; +import nl.healthri.fdp.uploadschema.dto.schema.SchemaDataResponseDto; +import nl.healthri.fdp.uploadschema.dto.auth.LoginResponseDto; import nl.healthri.fdp.uploadschema.integrations.FdpClientInterface; import nl.healthri.fdp.uploadschema.integrations.exceptions.FdpClientException; import nl.healthri.fdp.uploadschema.utils.SchemaInfo; -import nl.healthri.fdp.uploadschema.dto.Resource.ResourceResponse; +import nl.healthri.fdp.uploadschema.dto.resource.ResourceResponseDto; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -22,6 +23,8 @@ import java.util.*; +import static nl.healthri.fdp.uploadschema.config.fdp.Settings.*; + @Service public class FdpService implements FdpServiceInterface { @@ -35,27 +38,27 @@ public FdpService(FdpClientInterface fdpClient) { } public void authenticate(String username, String password) throws FdpClientException { - LoginRequest loginRequest = new LoginRequest(username, password); - LoginResponse loginResponse = fdpClient.getAuthToken(loginRequest); + LoginRequestDto loginRequest = new LoginRequestDto(username, password); + LoginResponseDto loginResponse = fdpClient.getAuthToken(loginRequest); fdpClient.setAuthToken(loginResponse); } - public List getAllSchemas() throws FdpClientException{ + public List getAllSchemas() throws FdpClientException{ return fdpClient.fetchSchemas(); } public void createSchema(ShapeTask task) throws FdpClientException { - List schemaDataResponseList = getAllSchemas(); + List schemaDataResponseList = getAllSchemas(); Map schemaInfoMap = new HashMap<>(); - for(SchemaDataResponse schemaDataResponse : schemaDataResponseList) { + for(SchemaDataResponseDto schemaDataResponse : schemaDataResponseList) { Version version = new Version(schemaDataResponse.latest().version()); SchemaInfo schemaInfo = new SchemaInfo(version, schemaDataResponse.uuid(), schemaDataResponse.latest().definition()); schemaInfoMap.put(schemaDataResponse.name(), schemaInfo); } - UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( + UpdateSchemaRequestDto updateSchemaRequest = new UpdateSchemaRequestDto( task.shape, task.description(), false, task.model, @@ -63,22 +66,22 @@ public void createSchema(ShapeTask task) throws FdpClientException { task.shape, task.url()); - ResourceResponse resourceResponse = fdpClient.insertSchema(task, updateSchemaRequest); + ResourceResponseDto resourceResponse = fdpClient.insertSchema(task, updateSchemaRequest); task.uuid = resourceResponse.uuid(); } public void updateSchema(ShapeTask task) throws FdpClientException { - List schemaDataResponseList = getAllSchemas(); + List schemaDataResponseList = getAllSchemas(); Map schemaInfoMap = new HashMap<>(); - for(SchemaDataResponse schemaDataResponse : schemaDataResponseList) { + for(SchemaDataResponseDto schemaDataResponse : schemaDataResponseList) { Version version = new Version(schemaDataResponse.latest().version()); SchemaInfo schemaInfo = new SchemaInfo(version, schemaDataResponse.uuid(), schemaDataResponse.latest().definition()); schemaInfoMap.put(schemaDataResponse.name(), schemaInfo); } - UpdateSchemaRequest updateSchemaRequest = new UpdateSchemaRequest( + UpdateSchemaRequestDto updateSchemaRequest = new UpdateSchemaRequestDto( task.shape, task.description(), false, task.model, @@ -90,17 +93,17 @@ public void updateSchema(ShapeTask task) throws FdpClientException { } public void releaseSchema(ShapeTask task) throws FdpClientException{ - ReleaseSchemaRequest releaseSchemaRequest = ReleaseSchemaRequest.of(task.shape, false, task.version); + ReleaseSchemaRequestDto releaseSchemaRequest = ReleaseSchemaRequestDto.of(task.shape, false, task.version); fdpClient.releaseSchema(task, releaseSchemaRequest); } - public List getAllResources() throws FdpClientException{ + public List getAllResources() throws FdpClientException{ return fdpClient.fetchResources(); } public void createResource(ResourceTask task) throws FdpClientException{ - ResourceRequest resourceRequest = new ResourceRequest( + ResourceRequestDto resourceRequest = new ResourceRequestDto( task.resource, task.url(), new ArrayList<>(List.of(task.shapeUUUID)), @@ -108,19 +111,19 @@ public void createResource(ResourceTask task) throws FdpClientException{ new ArrayList<>(), new ArrayList<>()); - ResourceResponse resourceResponse = fdpClient.insertResource(task, resourceRequest); + ResourceResponseDto resourceResponse = fdpClient.insertResource(task, resourceRequest); task.UUID = resourceResponse.uuid(); } public void updateResource(ResourceTask task) throws FdpClientException{ - ResourceResponse resourceResponse = fdpClient.fetchResource(task.UUID); + ResourceResponseDto resourceResponse = fdpClient.fetchResource(task.UUID); if (resourceResponse.children().stream().anyMatch(c -> c.resourceDefinitionUuid().equals(task.childUUuid))) { logger.info("resource {} already has link to child {}", resourceResponse.name(), task.childName); } else { //FIXME TagsURI is hardcoded.. - ResourceResponse.ListView listView = new ResourceResponse.ListView(task.pluralName(), "http://www.w3.org/ns/dcat#themeTaxonomy", new ArrayList<>()); - ResourceResponse.Child child = new ResourceResponse.Child(task.childUUuid, task.childRelationIri, listView); + ResourceResponseDto.ListView listView = new ResourceResponseDto.ListView(task.pluralName(), "http://www.w3.org/ns/dcat#themeTaxonomy", new ArrayList<>()); + ResourceResponseDto.Child child = new ResourceResponseDto.Child(task.childUUuid, task.childRelationIri, listView); resourceResponse.children().add(child); } @@ -128,9 +131,12 @@ public void updateResource(ResourceTask task) throws FdpClientException{ } public void updateSettings(Settings newSettings){ - SettingsResponse currentSettings = fdpClient.getSettings(); - Settings mergedSettings = newSettings.Merge(currentSettings); + SettingsResponseDto fdpSettingsResponseDto = fdpClient.getSettings(); + + Settings fdpSettings = convertToEntity(fdpSettingsResponseDto); + Settings mergedSettings = fdpSettings.Merge(newSettings); - fdpClient.updateSettings(mergedSettings); + SettingsRequestDto settingsRequestDto = SettingsRequestDto.convertToDto(mergedSettings); + fdpClient.updateSettings(settingsRequestDto); } } diff --git a/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java b/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java index 825e819..d9751d2 100644 --- a/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java +++ b/src/test/java/nl/healthri/fdp/uploadschema/config/SettingsTest.java @@ -1,11 +1,8 @@ package nl.healthri.fdp.uploadschema.config; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.DatabindException; import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; import nl.healthri.fdp.uploadschema.config.fdp.Settings; -import nl.healthri.fdp.uploadschema.dto.Settings.SettingsResponse; +import nl.healthri.fdp.uploadschema.dto.settings.SettingsResponseDto; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -33,40 +30,19 @@ void resetSettingsSingleton() throws Exception { } // Create a minimal SettingsResponse for merging - private SettingsResponse createMinimalFdpSettingsResponse() { - return new SettingsResponse( + private SettingsResponseDto createMinimalFdpSettingsResponse() { + return new SettingsResponseDto( "clientUrl", "persistentUrl", "appTitle", "appSubtitle", "appTitleConfig", "appSubtitleConfig", List.of(), - new SettingsResponse.Ping(true, List.of("e1"), List.of("e1c"), "1h"), - new SettingsResponse.Repository("type"), - new SettingsResponse.Search(List.of("f1")), - new SettingsResponse.Forms( - new SettingsResponse.Forms.Autocomplete( + new SettingsResponseDto.Ping(true, List.of("e1"), List.of("e1c"), "1h"), + new SettingsResponseDto.Repository("type"), + new SettingsResponseDto.Search(List.of("f1")), + new SettingsResponseDto.Forms( + new SettingsResponseDto.Forms.Autocomplete( true, List.of( - new SettingsResponse.Forms.Autocomplete.Source("FdpRdfType1", "fsparql1", "fquery1") - ) - ) - ) - ); - } - - // Create a SettingsResponse with an RDF Type used twice - private SettingsResponse createFdpSettingsResponseWithDuplicates() { - return new SettingsResponse( - "clientUrl", "persistentUrl", "appTitle", "appSubtitle", - "appTitleConfig", "appSubtitleConfig", - List.of(), - new SettingsResponse.Ping(true, List.of("e1"), List.of("e1c"), "1h"), - new SettingsResponse.Repository("type"), - new SettingsResponse.Search(List.of("f1")), - new SettingsResponse.Forms( - new SettingsResponse.Forms.Autocomplete( - true, - List.of( - new SettingsResponse.Forms.Autocomplete.Source("DuplicateRdfType", "fsparql1", "fquery1"), - new SettingsResponse.Forms.Autocomplete.Source("DuplicateRdfType", "fsparql2", "fquery2") // DUPLICATE + new SettingsResponseDto.Forms.Autocomplete.Source("FdpRdfType1", "fsparql1", "fquery1") ) ) ) @@ -97,28 +73,28 @@ public void SourceFoundInFdp_WhenMerging_ReturnsSettingsWithFdpSource() throws I // Setup FDP Settings with the same rdfType, but different query - SettingsResponse fdpSettings = new SettingsResponse( + SettingsResponseDto fdpSettings = new SettingsResponseDto( "clientUrl", "persistentUrl", "appTitle", "appSubtitle", "appTitleConfig", "appSubtitleConfig", List.of(), - new SettingsResponse.Ping(true, List.of(), List.of(), "1h"), - new SettingsResponse.Repository("type"), - new SettingsResponse.Search(List.of()), - new SettingsResponse.Forms( - new SettingsResponse.Forms.Autocomplete( + new SettingsResponseDto.Ping(true, List.of(), List.of(), "1h"), + new SettingsResponseDto.Repository("type"), + new SettingsResponseDto.Search(List.of()), + new SettingsResponseDto.Forms( + new SettingsResponseDto.Forms.Autocomplete( true, List.of( - new SettingsResponse.Forms.Autocomplete.Source(localRdfType, "fsparql", fdpQuery) + new SettingsResponseDto.Forms.Autocomplete.Source(localRdfType, "fsparql", fdpQuery) ) ) ) ); // ACT - settings = settings.Merge(fdpSettings); + settings = settings.Merge(Settings.convertToEntity(fdpSettings)); // ASSERT - assertEquals(2, settings.forms.autocomplete.sources.size(), "Should have 1 resource from settings and 1 resource from fdpSettings."); + assertEquals(1, settings.forms.autocomplete.sources.size(), "Should have 1 resource from settings and 1 resource from fdpSettings."); } @Test @@ -130,10 +106,10 @@ public void SourceMissingInFdpSettings_WhenMerging_ReturnsSettingsWithSource() t String jsonFdpSettings = "{\"forms\": {\"autocomplete\": {\"sources\": [{\"rdfType\": \"" + localRdfType + "\", \"sparqlQuery\": \"" + localQuery + "\"}]}}}"; File file = createFile(jsonFdpSettings); Settings settings = Settings.GetSettings(file); - SettingsResponse fdpSettings = createMinimalFdpSettingsResponse(); + SettingsResponseDto fdpSettings = createMinimalFdpSettingsResponse(); // ACT - settings = settings.Merge(fdpSettings); + settings = settings.Merge(Settings.convertToEntity(fdpSettings)); // ASSERT assertEquals(2, settings.forms.autocomplete.sources.size(), "Should have both local and FDP source."); @@ -151,14 +127,12 @@ public void SourceMissingInFdpSettings_WhenMerging_ReturnsSettingsWithSource() t } @Test - public void FileNotFound_WhenGettingSettings_ThrowsFileNotFoundException() throws IOException { + public void FileNotFound_WhenGettingSettings_ThrowsFileNotFoundException() { // ARRANGE File nonExistentFile = new File(tempDir, "nonExistent.json"); // ACT && ASSERT - assertThrows(FileNotFoundException.class, () -> { - Settings.GetSettings(nonExistentFile); - }); + assertThrows(FileNotFoundException.class, () -> Settings.GetSettings(nonExistentFile)); } @Test @@ -166,12 +140,9 @@ public void MalformedJsonFile_WhenGettingSettings_ThrowsIOException() throws IOE // ARRANGE String jsonFdpSettings = "{ \"forms\": { \"autocomplete\": \"invalid"; File file = createFile(jsonFdpSettings); - SettingsResponse fdpSettings = createMinimalFdpSettingsResponse(); // ACT & ASSERT - assertThrows(JsonMappingException.class, () -> { - Settings.GetSettings(file); - }); + assertThrows(JsonMappingException.class, () -> Settings.GetSettings(file)); } @Test From ddfc7c8e8cc7a37f596d9bab7afdc0654e5a26aa Mon Sep 17 00:00:00 2001 From: SeanBerrieHRI Date: Thu, 22 Jan 2026 14:30:38 +0100 Subject: [PATCH 51/51] refactor: remove preset form sources from FdpSettings.json --- FdpSettings.json | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/FdpSettings.json b/FdpSettings.json index 8e30a33..c21349c 100644 --- a/FdpSettings.json +++ b/FdpSettings.json @@ -3,26 +3,6 @@ "autocomplete": { "searchNamespace": true, "sources": [ - { - "rdfType": "http://purl.org/dc/terms/LinguisticSystem", - "sparqlEndpoint": "https://sparql-test.healthdata.nl/repositories/controlled-vocabularies", - "sparqlQuery": "PREFIX skos: \nSELECT ?entity ?entityLabel WHERE {\n ?entity skos:prefLabel ?entityLabel\n FILTER ( lang(?entityLabel) = \"en\")\n}\n" - }, - { - "rdfType": "http://purl.org/dc/terms/Frequency", - "sparqlEndpoint": "https://sparql-test.healthdata.nl/repositories/controlled-vocabularies", - "sparqlQuery": "PREFIX skos: \nSELECT ?entity ?entityLabel WHERE {\n GRAPH {\n ?entity skos:prefLabel ?entityLabel\n FILTER ( lang(?entityLabel) = \"en\")\n }\n}" - }, - { - "rdfType": "http://purl.org/dc/terms/MediaTypeOrExtent", - "sparqlEndpoint": "https://sparql-test.healthdata.nl/repositories/controlled-vocabularies", - "sparqlQuery": "PREFIX skos: \nSELECT ?entity ?entityLabel WHERE {\n GRAPH {\n ?entity skos:prefLabel ?entityLabel\n FILTER ( lang(?entityLabel) = \"en\")\n }\n}" - }, - { - "rdfType": "http://purl.org/dc/terms/Concept", - "sparqlEndpoint": "https://sparql-test.healthdata.nl/repositories/controlled-vocabularies", - "sparqlQuery": "PREFIX skos: \nSELECT ?entity ?entityLabel WHERE {\n GRAPH {\n ?entity skos:prefLabel ?entityLabel\n FILTER ( lang(?entityLabel) = \"en\")\n }\n}" - } ] } }