From aba8cd843042a3889541197216b359b3b85242cb Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Fri, 28 Sep 2018 16:23:02 +0100 Subject: [PATCH] Jackson serialization for processes --- .../refine/process/LongRunningProcess.java | 15 ++++++++++- .../com/google/refine/process/Process.java | 12 +++++++++ .../google/refine/process/ProcessManager.java | 27 +++++++++++++++++++ .../process/QuickHistoryEntryProcess.java | 18 ++++++++++--- .../tests/process/ProcessManagerTests.java | 16 ++++++----- 5 files changed, 78 insertions(+), 10 deletions(-) diff --git a/main/src/com/google/refine/process/LongRunningProcess.java b/main/src/com/google/refine/process/LongRunningProcess.java index b05b6e876..1e18949f4 100644 --- a/main/src/com/google/refine/process/LongRunningProcess.java +++ b/main/src/com/google/refine/process/LongRunningProcess.java @@ -38,13 +38,21 @@ import java.util.Properties; import org.json.JSONException; import org.json.JSONWriter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + import com.google.refine.history.HistoryEntry; abstract public class LongRunningProcess extends Process { + @JsonProperty("description") final protected String _description; + @JsonIgnore protected ProcessManager _manager; + @JsonIgnore protected Thread _thread; + @JsonProperty("progress") protected int _progress; // out of 100 + @JsonIgnore protected boolean _canceled; protected LongRunningProcess(String description) { @@ -67,10 +75,15 @@ abstract public class LongRunningProcess extends Process { writer.key("id"); writer.value(hashCode()); writer.key("description"); writer.value(_description); writer.key("immediate"); writer.value(false); - writer.key("status"); writer.value(_thread == null ? "pending" : (_thread.isAlive() ? "running" : "done")); + writer.key("status"); writer.value(getStatus()); writer.key("progress"); writer.value(_progress); writer.endObject(); } + + @JsonProperty("status") + public String getStatus() { + return _thread == null ? "pending" : (_thread.isAlive() ? "running" : "done"); + } @Override public boolean isImmediate() { diff --git a/main/src/com/google/refine/process/Process.java b/main/src/com/google/refine/process/Process.java index 14fbef20f..8b42bab71 100644 --- a/main/src/com/google/refine/process/Process.java +++ b/main/src/com/google/refine/process/Process.java @@ -33,17 +33,29 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.google.refine.process; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + import com.google.refine.Jsonizable; import com.google.refine.history.HistoryEntry; public abstract class Process implements Jsonizable { + @JsonProperty("immediate") abstract public boolean isImmediate(); + @JsonIgnore abstract public boolean isRunning(); + @JsonIgnore abstract public boolean isDone(); + @JsonIgnore abstract public HistoryEntry performImmediate() throws Exception; abstract public void startPerforming(ProcessManager manager); abstract public void cancel(); + + @JsonProperty("id") + public long getId() { + return hashCode(); + } } diff --git a/main/src/com/google/refine/process/ProcessManager.java b/main/src/com/google/refine/process/ProcessManager.java index 94cf150ed..6d22177fb 100644 --- a/main/src/com/google/refine/process/ProcessManager.java +++ b/main/src/com/google/refine/process/ProcessManager.java @@ -37,18 +37,34 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Properties; +import java.util.stream.Collectors; import org.json.JSONException; import org.json.JSONWriter; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; + import com.google.refine.Jsonizable; import com.google.refine.history.HistoryEntry; import com.google.refine.history.HistoryProcess; public class ProcessManager implements Jsonizable { + @JsonProperty("processes") protected List _processes = Collections.synchronizedList(new LinkedList()); + @JsonIgnore protected List _latestExceptions = null; + public static class ExceptionMessage { + @JsonProperty("message") + public final String message; + public ExceptionMessage(Exception e) { + message = e.getLocalizedMessage(); + } + } + public ProcessManager() { } @@ -78,6 +94,17 @@ public class ProcessManager implements Jsonizable { writer.endObject(); } + + @JsonProperty("exceptions") + @JsonInclude(Include.NON_NULL) + public List getJsonExceptions() { + if (_latestExceptions != null) { + return _latestExceptions.stream() + .map(e -> new ExceptionMessage(e)) + .collect(Collectors.toList()); + } + return null; + } public HistoryEntry queueProcess(Process process) throws Exception { if (process.isImmediate() && _processes.size() == 0) { diff --git a/main/src/com/google/refine/process/QuickHistoryEntryProcess.java b/main/src/com/google/refine/process/QuickHistoryEntryProcess.java index 96ed346b4..9d9c51726 100644 --- a/main/src/com/google/refine/process/QuickHistoryEntryProcess.java +++ b/main/src/com/google/refine/process/QuickHistoryEntryProcess.java @@ -38,6 +38,8 @@ import java.util.Properties; import org.json.JSONException; import org.json.JSONWriter; +import com.fasterxml.jackson.annotation.JsonProperty; + import com.google.refine.history.HistoryEntry; import com.google.refine.model.Project; @@ -58,6 +60,7 @@ abstract public class QuickHistoryEntryProcess extends Process { } @Override + @JsonProperty("immediate") public boolean isImmediate() { return true; } @@ -89,12 +92,21 @@ abstract public class QuickHistoryEntryProcess extends Process { writer.object(); writer.key("id"); writer.value(hashCode()); - writer.key("description"); writer.value(_historyEntry != null ? _historyEntry.description : _briefDescription); + writer.key("description"); writer.value(getDescription()); writer.key("immediate"); writer.value(true); - writer.key("status"); writer.value(_done ? "done" : "pending"); + writer.key("status"); writer.value(getStatus()); writer.endObject(); } - + + @JsonProperty("status") + public String getStatus() { + return _done ? "done" : "pending"; + } + + @JsonProperty("description") + public String getDescription() { + return _historyEntry != null ? _historyEntry.description : _briefDescription; + } @Override public boolean isDone() { diff --git a/main/tests/server/src/com/google/refine/tests/process/ProcessManagerTests.java b/main/tests/server/src/com/google/refine/tests/process/ProcessManagerTests.java index 2e34388c9..26e5b8f47 100644 --- a/main/tests/server/src/com/google/refine/tests/process/ProcessManagerTests.java +++ b/main/tests/server/src/com/google/refine/tests/process/ProcessManagerTests.java @@ -11,20 +11,24 @@ import com.google.refine.util.JSONUtilities; public class ProcessManagerTests { ProcessManager processManager; - Process process; + Process process1, process2; @BeforeMethod public void setUp() { processManager = new ProcessManager(); - process = new LongRunningProcessTests.LongRunningProcessStub("some description"); - + process1 = new LongRunningProcessTests.LongRunningProcessStub("some description"); + process2 = new LongRunningProcessTests.LongRunningProcessStub("some other description"); } @Test public void serializeProcessManager() throws Exception { - processManager.queueProcess(process); - String processJson = JSONUtilities.serialize(process); + processManager.queueProcess(process1); + processManager.queueProcess(process2); + processManager.onFailedProcess(process1, new IllegalArgumentException("unexpected error")); + String processJson = JSONUtilities.serialize(process2); TestUtils.isSerializedTo(processManager, "{" - + "\"processes\":["+processJson+"]}"); + + "\"processes\":["+processJson+"],\n" + + "\"exceptions\":[{\"message\":\"unexpected error\"}]" + + "}"); } }