-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new BiosimulationsLog to read/write biosimulations JSON log files
- Loading branch information
Showing
2 changed files
with
397 additions
and
0 deletions.
There are no files selected for viewing
98 changes: 98 additions & 0 deletions
98
vcell-core/src/main/java/org/vcell/sedml/log/BiosimulationLog.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package org.vcell.sedml.log; | ||
|
||
import com.fasterxml.jackson.annotation.JsonInclude; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.fasterxml.jackson.databind.SerializationFeature; | ||
|
||
import java.io.IOException; | ||
import java.math.BigDecimal; | ||
import java.nio.charset.StandardCharsets; | ||
import java.nio.file.Path; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class BiosimulationLog { | ||
|
||
public enum Status { | ||
QUEUED, | ||
SUCCEEDED, | ||
FAILED, | ||
SKIPPED | ||
} | ||
public static class ExceptionLog { | ||
public String type; | ||
public String message; | ||
} | ||
public static class DataSetLog { | ||
public String id; | ||
public Status status; | ||
} | ||
public static class CurveLog { | ||
public String id; | ||
public Status status; | ||
} | ||
public static class SkipReason { | ||
public String type; | ||
public String message; | ||
} | ||
public static class OutputLog { | ||
public String id; | ||
public Status status; | ||
public ExceptionLog exception; | ||
public SkipReason skipReason; | ||
public String output; | ||
public BigDecimal duration; | ||
@JsonInclude(JsonInclude.Include.NON_NULL) public List<DataSetLog> dataSets; | ||
@JsonInclude(JsonInclude.Include.NON_NULL) public List<CurveLog> curves; | ||
} | ||
public static class TaskLog { | ||
public String id; | ||
public Status status; | ||
public ExceptionLog exception; | ||
public SkipReason skipReason; | ||
public String output; | ||
public BigDecimal duration; | ||
public String algorithm; | ||
public String simulatorDetails; | ||
} | ||
public static class SedDocumentLog { | ||
public String location; | ||
public Status status; | ||
public ExceptionLog exception; | ||
public SkipReason skipReason; | ||
public String output; | ||
public BigDecimal duration; | ||
public List<TaskLog> tasks = new ArrayList<>(); | ||
public List<OutputLog> outputs = new ArrayList<>(); | ||
} | ||
public static class ArchiveLog { | ||
public Status status; | ||
public ExceptionLog exception; | ||
public SkipReason skipReason; | ||
public String output; | ||
public BigDecimal duration; | ||
public List<SedDocumentLog> sedDocuments = new ArrayList<>(); | ||
} | ||
|
||
public static ArchiveLog readArchiveLogFromJsonFile(Path path) throws IOException { | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
return objectMapper.readValue(path.toFile(), ArchiveLog.class); | ||
} | ||
|
||
public static ArchiveLog readArchiveLogFromJson(String json) throws IOException { | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
return objectMapper.readValue(json.getBytes(StandardCharsets.UTF_8), ArchiveLog.class); | ||
} | ||
|
||
public static void writeArchiveLogToJsonFile(ArchiveLog archiveLog, Path path) throws IOException { | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
objectMapper.enable(SerializationFeature.INDENT_OUTPUT); | ||
objectMapper.writeValue(path.toFile(), archiveLog); | ||
} | ||
|
||
public static String writeArchiveLogToJson(ArchiveLog archiveLog) throws IOException { | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
objectMapper.enable(SerializationFeature.INDENT_OUTPUT); | ||
return objectMapper.writeValueAsString(archiveLog); | ||
} | ||
} |
299 changes: 299 additions & 0 deletions
299
vcell-core/src/test/java/org/vcell/sedml/log/BiosimulationLogTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,299 @@ | ||
package org.vcell.sedml.log; | ||
|
||
import com.fasterxml.jackson.databind.JsonNode; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.fasterxml.jackson.databind.SerializationFeature; | ||
import org.junit.jupiter.api.Tag; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.MethodSource; | ||
|
||
import java.io.IOException; | ||
import java.util.Collection; | ||
import java.util.List; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
@Tag("Fast") | ||
public class BiosimulationLogTest { | ||
static String json_element_beginning = """ | ||
{ | ||
"status": "QUEUED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": null, | ||
"sedDocuments": [ | ||
{ | ||
"location": "doc_1.sedml", | ||
"status": "QUEUED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": null, | ||
"tasks": [ | ||
{ | ||
"id": "task_1_ss", | ||
"status": "QUEUED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": null, | ||
"algorithm": null, | ||
"simulatorDetails": null | ||
}, | ||
{ | ||
"id": "task_2_time_course", | ||
"status": "QUEUED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": null, | ||
"algorithm": null, | ||
"simulatorDetails": null | ||
} | ||
], | ||
"outputs": [ | ||
{ | ||
"id": "report_1", | ||
"status": "QUEUED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": null, | ||
"dataSets": [ | ||
{ | ||
"id": "dataset_1", | ||
"status": "QUEUED" | ||
}, | ||
{ | ||
"id": "dataset_2", | ||
"status": "QUEUED" | ||
} | ||
] | ||
}, | ||
{ | ||
"id": "plot_1", | ||
"status": "QUEUED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": null, | ||
"curves": [ | ||
{ | ||
"id": "curve_1", | ||
"status": "QUEUED" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
] | ||
} | ||
"""; | ||
static String json_element_success = """ | ||
{ | ||
"status": "SUCCEEDED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": 6, | ||
"sedDocuments": [ | ||
{ | ||
"location": "doc_1.sedml", | ||
"status": "SUCCEEDED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": 5, | ||
"tasks": [ | ||
{ | ||
"id": "task_1_ss", | ||
"status": "SUCCEEDED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": "Reading model ... done\\nInitializing simulation ... done\\nExecuting simulation ... done\\n", | ||
"duration": 2, | ||
"algorithm": null, | ||
"simulatorDetails": null | ||
}, | ||
{ | ||
"id": "task_2_time_course", | ||
"status": "SUCCEEDED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": "Reading model ... done\\nInitializing simulation ... done\\nExecuting simulation ... done\\n", | ||
"duration": 1, | ||
"algorithm": null, | ||
"simulatorDetails": null | ||
} | ||
], | ||
"outputs": [ | ||
{ | ||
"id": "report_1", | ||
"status": "SUCCEEDED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": 0.1, | ||
"dataSets": [ | ||
{ | ||
"id": "dataset_1", | ||
"status": "SUCCEEDED" | ||
}, | ||
{ | ||
"id": "dataset_2", | ||
"status": "SUCCEEDED" | ||
} | ||
] | ||
}, | ||
{ | ||
"id": "plot_1", | ||
"status": "SUCCEEDED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": 0.01, | ||
"curves": [ | ||
{ | ||
"id": "curve_1", | ||
"status": "SUCCEEDED" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
] | ||
} | ||
"""; | ||
static String json_element_failure = """ | ||
{ | ||
"status": "FAILED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": 6, | ||
"sedDocuments": [ | ||
{ | ||
"location": "doc_1.sedml", | ||
"status": "FAILED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": 5, | ||
"tasks": [ | ||
{ | ||
"id": "task_1_ss", | ||
"status": "SUCCEEDED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": "Reading model ... done\\nInitializing simulation ... done\\nExecuting simulation ... done\\n", | ||
"duration": 2, | ||
"algorithm": null, | ||
"simulatorDetails": null | ||
}, | ||
{ | ||
"id": "task_2_time_course", | ||
"status": "FAILED", | ||
"exception": { | ||
"type": "FileNotFoundError", | ||
"message": "Model `model2.xml` does not exist." | ||
}, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": 1, | ||
"algorithm": null, | ||
"simulatorDetails": null | ||
} | ||
], | ||
"outputs": [ | ||
{ | ||
"id": "report_1", | ||
"status": "SUCCEEDED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": 0.1, | ||
"dataSets": [ | ||
{ | ||
"id": "dataset_1", | ||
"status": "SUCCEEDED" | ||
}, | ||
{ | ||
"id": "dataset_2", | ||
"status": "SUCCEEDED" | ||
} | ||
] | ||
}, | ||
{ | ||
"id": "plot_1", | ||
"status": "SKIPPED", | ||
"exception": null, | ||
"skipReason": { | ||
"type": "2DPlotNotImplemented", | ||
"message": "Output skipped because the simulator cannot generate plots." | ||
}, | ||
"output": null, | ||
"duration": 0.01, | ||
"curves": [ | ||
{ | ||
"id": "curve_1", | ||
"status": "SKIPPED" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
] | ||
} | ||
"""; | ||
static String json_document_failed = """ | ||
{ | ||
"status": "FAILED", | ||
"exception": null, | ||
"skipReason": null, | ||
"output": null, | ||
"duration": 6, | ||
"sedDocuments": [ | ||
{ | ||
"location": "doc_1.sedml", | ||
"status": "FAILED", | ||
"exception": { | ||
"type": "FileNotFoundError", | ||
"message": "Model `model2.xml` does not exist." | ||
}, | ||
"skipReason": null, | ||
"output": "Reading model ... done\\nInitializing simulation ... done\\nExecuting simulation ... done\\n", | ||
"duration": 5, | ||
"tasks": null, | ||
"outputs": null | ||
} | ||
] | ||
} | ||
"""; | ||
|
||
public static Collection<String> testCases() { | ||
return List.of(json_element_beginning, json_element_success, json_element_failure, json_document_failed); | ||
} | ||
|
||
@ParameterizedTest | ||
@MethodSource("testCases") | ||
public void testArchiveLogRead(String expectedJson) throws IOException { | ||
// create ArchiveLog from given JSON | ||
BiosimulationLog.ArchiveLog archiveLog = BiosimulationLog.readArchiveLogFromJson(expectedJson); | ||
|
||
// generate new JSON string from ArchiveLog | ||
String newJson = BiosimulationLog.writeArchiveLogToJson(archiveLog); | ||
|
||
// compare the original JSON string with the new JSON string - normalize by pretty printing | ||
assertEquals(prettyPrintJson(expectedJson), prettyPrintJson(newJson)); | ||
} | ||
|
||
|
||
public static String prettyPrintJson(String jsonString) throws IOException { | ||
ObjectMapper objectMapper = new ObjectMapper(); | ||
JsonNode jsonNode = objectMapper.readTree(jsonString); | ||
objectMapper.enable(SerializationFeature.INDENT_OUTPUT); | ||
return objectMapper.writeValueAsString(jsonNode); | ||
} | ||
|
||
} |