Add timestamp to Actions (#2113)

* Add timestamp to Actions

Signed-off-by: Vasil Ilchev <Vasil.Ilchev@bosch.com>

* Add Timestamp to All Actions Feedback DDI/DMF

* After review

* Removed Action timestamp as we have timestamp in each ActionStatus so use that instead

* Unify to use everywhere System.currentTimeMillis()

* Add constructor w/o timestamp to DmfActionUpdateStatus

---------

Signed-off-by: Vasil Ilchev <Vasil.Ilchev@bosch.com>
Co-authored-by: vasilchev <vasil.ilchev@bosch.com>
This commit is contained in:
Vasil Ilchev
2024-12-04 09:53:10 +02:00
committed by GitHub
parent 58e427d1ea
commit b4215a9d76
17 changed files with 96 additions and 64 deletions

View File

@@ -31,7 +31,7 @@ import lombok.Data;
*
* <p>
* The answer header would look like: {
* "time": "20140511T121314",
* "timestamp": "1733218554123",
* "status": {
* "execution": "closed",
* "result": {
@@ -47,8 +47,8 @@ import lombok.Data;
@JsonIgnoreProperties(ignoreUnknown = true)
public class DdiActionFeedback {
@Schema(description = "Timestamp of the action", example = "2023-08-03T12:31:41.890992967Z")
private final String time;
@Schema(description = "Timestamp of the action in milliseconds since epoch", example = "1627997501890")
private final Long timestamp;
@NotNull
@Valid
@@ -57,14 +57,19 @@ public class DdiActionFeedback {
/**
* Constructs an action-feedback
*
* @param time time of feedback
* @param timestamp time of feedback
* @param status status to be appended to the action
*/
@JsonCreator
public DdiActionFeedback(
@JsonProperty(value = "time") final String time,
@JsonProperty(value = "status", required = true) final DdiStatus status) {
this.time = time;
@JsonProperty(value = "status", required = true) final DdiStatus status,
@JsonProperty(value = "timestamp") final Long timestamp) {
this.status = status;
this.timestamp = timestamp != null ? timestamp : System.currentTimeMillis();
}
public DdiActionFeedback(final DdiStatus status) {
this(status, null);
}
}

View File

@@ -39,7 +39,7 @@ class DdiActionFeedbackTest {
void shouldSerializeAndDeserializeObjectWithoutOptionalValues() throws IOException {
// Setup
final DdiStatus ddiStatus = new DdiStatus(DdiStatus.ExecutionStatus.CLOSED, null, null, Collections.emptyList());
final DdiActionFeedback ddiActionFeedback = new DdiActionFeedback(null, ddiStatus);
final DdiActionFeedback ddiActionFeedback = new DdiActionFeedback(ddiStatus);
// Test
final String serializedDdiActionFeedback = mapper.writeValueAsString(ddiActionFeedback);
@@ -53,17 +53,16 @@ class DdiActionFeedbackTest {
@Description("Verify the correct serialization and deserialization of the model with all values provided")
void shouldSerializeAndDeserializeObjectWithOptionalValues() throws IOException {
// Setup
final String time = Instant.now().toString();
final Long timestamp = System.currentTimeMillis();
final DdiResult ddiResult = new DdiResult(DdiResult.FinalResult.SUCCESS, new DdiProgress(10, 10));
final DdiStatus ddiStatus = new DdiStatus(DdiStatus.ExecutionStatus.CLOSED, ddiResult, 200, Collections.singletonList("myMessage"));
final DdiActionFeedback ddiActionFeedback = new DdiActionFeedback(time, ddiStatus);
final DdiActionFeedback ddiActionFeedback = new DdiActionFeedback(ddiStatus, timestamp);
// Test
final String serializedDdiActionFeedback = mapper.writeValueAsString(ddiActionFeedback);
final DdiActionFeedback deserializedDdiActionFeedback = mapper.readValue(serializedDdiActionFeedback, DdiActionFeedback.class);
assertThat(serializedDdiActionFeedback).contains(time);
assertThat(deserializedDdiActionFeedback.getTime()).isEqualTo(time);
assertThat(deserializedDdiActionFeedback.getTimestamp()).isEqualTo(timestamp);
assertThat(deserializedDdiActionFeedback.getStatus()).hasToString(ddiStatus.toString());
}
@@ -71,28 +70,38 @@ class DdiActionFeedbackTest {
@Description("Verify that deserialization fails for known properties with a wrong datatype")
void shouldFailForObjectWithWrongDataTypes() throws IOException {
// Setup
final String serializedDdiActionFeedback = "{\"time\":\"20190809T121314\",\"status\":{\"execution\": [closed],\"result\":null,\"details\":[]}}";
final String serializedDdiActionFeedback = """
{
"timestamp" : "1627997501890",
"status" : {
"execution" : "[closed]",
"result" : null,
"details" : []
}
}
""";
assertThatExceptionOfType(MismatchedInputException.class).isThrownBy(
() -> mapper.readValue(serializedDdiActionFeedback, DdiActionFeedback.class));
}
@Test
@Description("Verify that deserialization works if optional fields are not parsed")
void shouldConvertItWithoutOptionalFieldTime() throws JsonProcessingException {
void shouldConvertItWithoutOptionalFieldTimestamp() throws JsonProcessingException {
// Setup
final String serializedDdiActionFeedback = "{\n" + //
" \"status\" : {\n" + //
" \"result\" : {\n" + //
" \"finished\" : \"none\"\n" + //
" },\n" + //
" \"execution\" : \"download\",\n" + //
" \"details\" : [ \"Some message\" ]\n" + //
" }\n" + //
"}";//
final String serializedDdiActionFeedback = """
{
"status" : {
"result" : {
"finished" : "none"
},
"execution" : "download",
"details" : [ "Some message" ]
}
}
""";
assertThat(mapper.readValue(serializedDdiActionFeedback, DdiActionFeedback.class)).satisfies(deserializedDdiActionFeedback -> {
assertThat(deserializedDdiActionFeedback.getTime()).isNull();
assertThat(deserializedDdiActionFeedback.getTimestamp()).isNotNull();
assertThat(deserializedDdiActionFeedback.getStatus()).isNotNull();
assertThat(deserializedDdiActionFeedback.getStatus().getResult()).isNotNull();
assertThat(deserializedDdiActionFeedback.getStatus().getResult().getFinished()).isEqualTo(DdiResult.FinalResult.NONE);