Repository: gchq/sleeper
Issue: Exception generated when querying finished Compaction Task

```
Exception in thread "main" java.lang.NumberFormatException: For input string: "1416.976"
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Long.parseLong(Long.java:589)
	at java.lang.Long.parseLong(Long.java:631)
	at sleeper.compaction.status.DynamoDBAttributes.getLongAttribute(DynamoDBAttributes.java:75)
	at sleeper.compaction.status.task.DynamoDBCompactionTaskStatusFormat.addStatusUpdate(DynamoDBCompactionTaskStatusFormat.java:106)
	at sleeper.compaction.status.task.DynamoDBCompactionTaskStatusFormat.lambda$streamTaskStatuses$0(DynamoDBCompactionTaskStatusFormat.java:90)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at sleeper.compaction.status.task.DynamoDBCompactionTaskStatusFormat.streamTaskStatuses(DynamoDBCompactionTaskStatusFormat.java:90)
	at sleeper.compaction.status.task.DynamoDBCompactionTaskStatusStore.getTasksInProgress(DynamoDBCompactionTaskStatusStore.java:105)
	at sleeper.status.report.CompactionTaskStatusReport.run(CompactionTaskStatusReport.java:51)
	at sleeper.status.report.StatusReport.run(StatusReport.java:99)
	at sleeper.status.report.StatusReport.main(StatusReport.java:130)
```
Looks like duration for jobs is stored as double but retrieved as a long in DynamoDBCompactionTaskStatusFormat.

Changed files:
java/compaction-status-store/src/main/java/sleeper/compaction/status/task/DynamoDBCompactionTaskStatusFormat.java
java/compaction-status-store/src/test/java/sleeper/compaction/status/testutils/DynamoDBCompactionTaskStatusStoreTestBase.java
java/compaction-status-store/src/test/java/sleeper/compaction/status/task/StoreCompactionTaskIT.java

diff --git a/java/compaction-status-store/src/main/java/sleeper/compaction/status/task/DynamoDBCompactionTaskStatusFormat.java b/java/compaction-status-store/src/main/java/sleeper/compaction/status/task/DynamoDBCompactionTaskStatusFormat.java
index 955bec6b8..1c4ab4fea 100644
--- a/java/compaction-status-store/src/main/java/sleeper/compaction/status/task/DynamoDBCompactionTaskStatusFormat.java
+++ b/java/compaction-status-store/src/main/java/sleeper/compaction/status/task/DynamoDBCompactionTaskStatusFormat.java
@@ -100,7 +100,7 @@ public class DynamoDBCompactionTaskStatusFormat {
             case FINISHED:
                 builder.taskFinished(taskId, CompactionTaskFinishedStatus.builder()
                                 .finishTime(getInstantAttribute(item, FINISH_TIME))
-                                .totalRuntimeInSeconds(getLongAttribute(item, DURATION, 0))
+                                .totalRuntimeInSeconds(Double.parseDouble(getNumberAttribute(item, DURATION)))
                                 .totalJobs(getIntAttribute(item, NUMBER_OF_JOBS, 0))
                                 .totalRecordsRead(getLongAttribute(item, LINES_READ, 0))
                                 .totalRecordsWritten(getLongAttribute(item, LINES_WRITTEN, 0))
diff --git a/java/compaction-status-store/src/test/java/sleeper/compaction/status/task/StoreCompactionTaskIT.java b/java/compaction-status-store/src/test/java/sleeper/compaction/status/task/StoreCompactionTaskIT.java
index b0066da2b..457ffcfad 100644
--- a/java/compaction-status-store/src/test/java/sleeper/compaction/status/task/StoreCompactionTaskIT.java
+++ b/java/compaction-status-store/src/test/java/sleeper/compaction/status/task/StoreCompactionTaskIT.java
@@ -52,6 +52,22 @@ public class StoreCompactionTaskIT extends DynamoDBCompactionTaskStatusStoreTest
                 .isEqualTo(taskStatus);
     }
 
+    @Test
+    public void shouldReportCompactionTaskFinishedWithDurationInSecondsNotAWholeNumber() {
+        // Given
+        CompactionTaskStatus taskStatus = finishedTaskWithDefaultsAndDurationInSecondsNotAWholeNumber();
+
+        // When
+        store.taskStarted(taskStatus);
+        store.taskFinished(taskStatus);
+
+        // Then
+        assertThat(store.getTask(taskStatus.getTaskId()))
+                .usingRecursiveComparison(IGNORE_EXPIRY_DATE)
+                .isEqualTo(taskStatus);
+
+    }
+
     @Test
     public void shouldReportNoCompactionTaskExistsInStore() {
         // Given
diff --git a/java/compaction-status-store/src/test/java/sleeper/compaction/status/testutils/DynamoDBCompactionTaskStatusStoreTestBase.java b/java/compaction-status-store/src/test/java/sleeper/compaction/status/testutils/DynamoDBCompactionTaskStatusStoreTestBase.java
index cb4b6035d..fa3b1742b 100644
--- a/java/compaction-status-store/src/test/java/sleeper/compaction/status/testutils/DynamoDBCompactionTaskStatusStoreTestBase.java
+++ b/java/compaction-status-store/src/test/java/sleeper/compaction/status/testutils/DynamoDBCompactionTaskStatusStoreTestBase.java
@@ -52,35 +52,52 @@ public class DynamoDBCompactionTaskStatusStoreTestBase extends DynamoDBTestBase
         dynamoDBClient.deleteTable(taskStatusTableName);
     }
 
-    protected static Instant defaultStartTime() {
+    private static Instant defaultJobStartTime() {
+        return Instant.parse("2022-09-22T14:00:04.000Z");
+    }
+
+    private static Instant defaultJobFinishTime() {
+        return Instant.parse("2022-09-22T14:00:14.000Z");
+    }
+
+    private static Instant defaultTaskStartTime() {
         return Instant.parse("2022-09-22T12:30:00.000Z");
     }
 
-    protected static Instant defaultFinishTime() {
+    private static Instant defaultTaskFinishTime() {
         return Instant.parse("2022-09-22T16:30:00.000Z");
     }
 
+    private static Instant taskFinishTimeWithDurationInSecondsNotAWholeNumber() {
+        return Instant.parse("2022-09-22T16:30:00.500Z");
+    }
+
+    private static CompactionJobSummary defaultJobSummary() {
+        return new CompactionJobSummary(
+                new CompactionJobRecordsProcessed(4800L, 2400L),
+                defaultJobStartTime(), defaultJobFinishTime());
+    }
+
     protected static CompactionTaskStatus startedTaskWithDefaults() {
         return startedTaskWithDefaultsBuilder().build();
     }
 
     protected static CompactionTaskStatus.Builder startedTaskWithDefaultsBuilder() {
-        return CompactionTaskStatus.builder().taskId(UUID.randomUUID().toString()).started(defaultStartTime());
+        return CompactionTaskStatus.builder().taskId(UUID.randomUUID().toString()).started(defaultTaskStartTime());
     }
 
     protected static CompactionTaskStatus finishedTaskWithDefaults() {
         return startedTaskWithDefaultsBuilder().finished(
                 CompactionTaskFinishedStatus.builder()
                         .addJobSummary(defaultJobSummary()),
-                defaultFinishTime().toEpochMilli()).build();
+                defaultTaskFinishTime().toEpochMilli()).build();
     }
 
-    private static CompactionJobSummary defaultJobSummary() {
-        Instant jobStartedUpdateTime = Instant.parse("2022-09-22T14:00:04.000Z");
-        Instant jobFinishTime = Instant.parse("2022-09-22T14:00:14.000Z");
-        return new CompactionJobSummary(
-                new CompactionJobRecordsProcessed(4800L, 2400L),
-                jobStartedUpdateTime, jobFinishTime);
+    protected static CompactionTaskStatus finishedTaskWithDefaultsAndDurationInSecondsNotAWholeNumber() {
+        return startedTaskWithDefaultsBuilder().finished(
+                CompactionTaskFinishedStatus.builder()
+                        .addJobSummary(defaultJobSummary()),
+                taskFinishTimeWithDurationInSecondsNotAWholeNumber().toEpochMilli()).build();
     }
 
     protected static CompactionTaskStatus taskWithStartTime(Instant startTime) {