Permalink
Browse files

Merge branch 'model_refactor' of github.com:twitter/ambrose into mode…

…l_refactor

Conflicts:
	common/src/test/java/com/twitter/ambrose/service/impl/InMemoryStatsServiceTest.java
  • Loading branch information...
2 parents 311fb3e + 0974c60 commit d607c293551ed0a890a94feb77f040fa6dadb78c @sagemintblue sagemintblue committed Apr 3, 2013
@@ -13,14 +13,13 @@
See the License for the specific language governing permissions and
limitations under the License.
*/
-package com.twitter.ambrose.service;
+package com.twitter.ambrose.model;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
-import com.twitter.ambrose.model.Job;
import org.codehaus.jackson.annotate.JsonCreator;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
@@ -32,7 +31,7 @@
/**
* Class that represents a Job node in the DAG. The job name must not be null. At DAG creation time
* the jobID will probably be null. Ideally this will be set on the node when the job is started,
- * and the node will be sent as a <pre>WorkflowEvent.EVENT_TYPE.JOB_STARTED</pre> event.
+ * and the node will be sent as a <pre>Event.Type.JOB_STARTED</pre> event.
*
* This class can be converted to JSON as-is by doing something like this:
*
@@ -0,0 +1,133 @@
+/*
+Copyright 2012 Twitter, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package com.twitter.ambrose.model;
+
+import com.twitter.ambrose.util.JSONUtil;
+import org.codehaus.jackson.type.TypeReference;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Class that represents a Event of a given Type. Each one of these created will have
+ * a unique id that increments up for each object. eventIds will always be >= 0.
+ * The data associated with the event currently can be anything.
+ *
+ * @author billg
+ */
+public class Event<T> {
+ private static AtomicInteger NEXT_ID = new AtomicInteger();
+
+ public static enum Type { JOB_STARTED, JOB_FINISHED, JOB_FAILED, JOB_PROGRESS, WORKFLOW_PROGRESS};
+
+ public static enum WorkflowProgressField {
+ workflowProgress;
+ }
+
+ private long timestamp;
+ private int id;
+ private Type type;
+ private T payload;
+
+ private Event(Type type, T payload) {
+ this.id = NEXT_ID.incrementAndGet();
+ this.timestamp = System.currentTimeMillis();
+ this.type = type;
+ this.payload = payload;
+ }
+
+ private Event(int eventId, long timestamp, Type type, T payload) {
+ this.id = eventId;
+ this.timestamp = timestamp;
+ this.type = type;
+ this.payload = payload;
+ }
+
+ public long getTimestamp() { return timestamp; }
+ public int getId() { return id; }
+ public Type getType() { return type; }
+ public Object getPayload() { return payload; }
+
+ @SuppressWarnings("unchecked")
+ public static void main(String[] args) throws IOException {
+ String json = JSONUtil.readFile("pig/src/main/resources/web/data/small-events.json");
+ List<Event> events =
+ (List<Event>)JSONUtil.readJson(json, new TypeReference<List<Event>>() { });
+// for (Event event : events) {
+// // useful if we need to read a file, add a field, output and re-generate
+// }
+
+ JSONUtil.writeJson("pig/src/main/resources/web/data/small-events.json2", events);
+ }
+
+ /**
+ * Helper method to create instances of the proper event. It is the reposibility of the caller to
+ * assure that their types are aligned with
+ * @param type
+ * @param data
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public static Event create(Type type, Object data) {
+ switch (type) {
+ case JOB_STARTED:
+ return new JobStartedEvent((DAGNode<Job>) data);
+ case JOB_PROGRESS:
+ return new JobStartedEvent((DAGNode<Job>) data);
+ case JOB_FINISHED:
+ return new JobFinishedEvent((DAGNode<Job>) data);
+ case JOB_FAILED:
+ return new JobStartedEvent((DAGNode<Job>) data);
+ case WORKFLOW_PROGRESS:
+ return new JobStartedEvent((DAGNode<Job>) data);
+ default:
+ throw new IllegalArgumentException(
+ String.format("Unknown event type %s for data payload %s", type, data));
+ }
+ }
+
+ public static class JobStartedEvent extends Event<DAGNode<? extends Job>> {
+ public JobStartedEvent(DAGNode<? extends Job> eventData) {
+ super(Type.JOB_STARTED, eventData);
+ }
+ }
+
+ public static class JobProgressEvent extends Event<DAGNode<? extends Job>> {
+ public JobProgressEvent(DAGNode<? extends Job> eventData) {
+ super(Type.JOB_PROGRESS, eventData);
+ }
+ }
+
+ public static class JobFinishedEvent extends Event<DAGNode<? extends Job>> {
+ public JobFinishedEvent(DAGNode<? extends Job> eventData) {
+ super(Type.JOB_FINISHED, eventData);
+ }
+ }
+
+ public static class JobFailedEvent extends Event<DAGNode<? extends Job>> {
+ public JobFailedEvent(DAGNode<? extends Job> eventData) {
+ super(Type.JOB_FAILED, eventData);
+ }
+ }
+
+ public static class WorkflowProgressEvent extends Event<Map<WorkflowProgressField, String>> {
+ public WorkflowProgressEvent(Map<WorkflowProgressField, String> eventData) {
+ super(Type.WORKFLOW_PROGRESS, eventData);
+ }
+ }
+}
@@ -35,14 +35,14 @@
@JsonSerialize(
include=JsonSerialize.Inclusion.NON_NULL
)
-public class WorkflowInfo {
+public class Workflow {
private String workflowId;
private String workflowFingerprint;
private List<Job> jobs;
/**
- * Creates a new immutable WorkflowInfo object.
+ * Creates a new immutable Workflow object.
*
* @param workflowId the id of the workflow. This surrogate id should distinguish between one
* workflow invocation and another.
@@ -52,9 +52,9 @@
* @param jobs
*/
@JsonCreator
- public WorkflowInfo(@JsonProperty("workflowId") String workflowId,
- @JsonProperty("workflowFingerprint") String workflowFingerprint,
- @JsonProperty("jobs") List<Job> jobs) {
+ public Workflow(@JsonProperty("workflowId") String workflowId,
+ @JsonProperty("workflowFingerprint") String workflowFingerprint,
+ @JsonProperty("jobs") List<Job> jobs) {
this.workflowId = workflowId;
this.workflowFingerprint = workflowFingerprint;
this.jobs = jobs;
@@ -65,29 +65,29 @@ public WorkflowInfo(@JsonProperty("workflowId") String workflowId,
public List<Job> getJobs() { return jobs; }
/**
- * Serializes a WorkflowInfo object and it's children into a JSON String.
+ * Serializes a Workflow object and it's children into a JSON String.
*
- * @param workflowInfo the object to serialize
+ * @param workflow the object to serialize
* @return a JSON string.
* @throws IOException
*/
- public static String toJSON(WorkflowInfo workflowInfo) throws IOException {
+ public static String toJSON(Workflow workflow) throws IOException {
ObjectMapper om = new ObjectMapper();
om.getSerializationConfig().set(SerializationConfig.Feature.INDENT_OUTPUT, true);
- return om.writeValueAsString(workflowInfo);
+ return om.writeValueAsString(workflow);
}
/**
- * Derializes a JSON WorkflowInfo string into a WorkflowInfo object. Unrecognized properties will
+ * Derializes a JSON Workflow string into a Workflow object. Unrecognized properties will
* be ignored.
*
* @param workflowInfoJson the string to convert into a JSON object.
- * @return a WorkflowInfo object.
+ * @return a Workflow object.
* @throws IOException
*/
- public static WorkflowInfo fromJSON(String workflowInfoJson) throws IOException {
+ public static Workflow fromJSON(String workflowInfoJson) throws IOException {
ObjectMapper om = new ObjectMapper();
om.getDeserializationConfig().set(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
- return om.readValue(workflowInfoJson, WorkflowInfo.class);
+ return om.readValue(workflowInfoJson, Workflow.class);
}
}
@@ -7,13 +7,13 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import com.twitter.ambrose.model.DAGNode;
+import com.twitter.ambrose.model.Event;
import org.mortbay.jetty.HttpConnection;
import org.mortbay.jetty.Request;
import org.mortbay.jetty.handler.AbstractHandler;
-import com.twitter.ambrose.service.DAGNode;
import com.twitter.ambrose.service.StatsReadService;
-import com.twitter.ambrose.service.WorkflowEvent;
import com.twitter.ambrose.util.JSONUtil;
/**
@@ -54,10 +54,10 @@ public void handle(String target,
Integer sinceId = request.getParameter(QUERY_PARAM_LAST_EVENT_ID) != null ?
Integer.parseInt(request.getParameter(QUERY_PARAM_LAST_EVENT_ID)) : -1;
- Collection<WorkflowEvent> events =
+ Collection<Event> events =
statsReadService.getEventsSinceId(request.getParameter(QUERY_PARAM_WORKFLOW_ID), sinceId);
- sendJson(request, response, events.toArray(new WorkflowEvent[events.size()]));
+ sendJson(request, response, events.toArray(new Event[events.size()]));
}
else if (target.endsWith(".html")) {
response.setContentType(MIME_TYPE_HTML);
@@ -15,6 +15,8 @@
*/
package com.twitter.ambrose.service;
+import com.twitter.ambrose.model.DAGNode;
+
import java.util.Collection;
/**
@@ -15,6 +15,8 @@
*/
package com.twitter.ambrose.service;
+import com.twitter.ambrose.model.DAGNode;
+import com.twitter.ambrose.model.Event;
import com.twitter.ambrose.model.Job;
import java.io.IOException;
@@ -45,5 +47,5 @@
* @param eventId the eventId that all returned events will be greater than
* @return a Collection of WorkflowEvents, ordered by eventId ascending
*/
- public Collection<WorkflowEvent> getEventsSinceId(String workflowId, int eventId) throws IOException;
+ public Collection<Event> getEventsSinceId(String workflowId, int eventId) throws IOException;
}
@@ -15,6 +15,8 @@
*/
package com.twitter.ambrose.service;
+import com.twitter.ambrose.model.DAGNode;
+import com.twitter.ambrose.model.Event;
import com.twitter.ambrose.model.Job;
import java.io.IOException;
@@ -45,5 +47,5 @@
* @param workflowId the id of the workflow being updated
* @param event the event bound to the workflow
*/
- public void pushEvent(String workflowId, WorkflowEvent event) throws IOException;
+ public void pushEvent(String workflowId, Event event) throws IOException;
}
@@ -1,77 +0,0 @@
-/*
-Copyright 2012 Twitter, Inc.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-package com.twitter.ambrose.service;
-
-import com.twitter.ambrose.util.JSONUtil;
-import org.codehaus.jackson.type.TypeReference;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Class that represents a WorkflowEvent of a given EVENT_TYPE. Each one of these created will have
- * a unique eventId that increments up for each object. eventIds will always be >= 0.
- * The data associated with the event currently can be anything.
- * TODO: can we type eventData better?
- *
- * @author billg
- */
-public class WorkflowEvent {
- private static AtomicInteger NEXT_ID = new AtomicInteger();
-
- public static enum EVENT_TYPE { JOB_STARTED, JOB_FINISHED, JOB_FAILED, JOB_PROGRESS, WORKFLOW_PROGRESS};
-
- private long timestamp;
- private int eventId;
- private String runtime;
- private EVENT_TYPE eventType;
- private Object eventData;
-
- public WorkflowEvent(EVENT_TYPE eventType, Object eventData, String runtime) {
- this.eventId = NEXT_ID.incrementAndGet();
- this.timestamp = System.currentTimeMillis();
- this.eventType = eventType;
- this.eventData = eventData;
- this.runtime = runtime;
- }
-
- public WorkflowEvent(int eventId, long timestamp, EVENT_TYPE eventType, Object eventData, String runtime) {
- this.eventId = eventId;
- this.timestamp = timestamp;
- this.eventType = eventType;
- this.eventData = eventData;
- this.runtime = runtime;
- }
-
- public long getTimestamp() { return timestamp; }
- public int getEventId() { return eventId; }
- public EVENT_TYPE getEventType() { return eventType; }
- public Object getEventData() { return eventData; }
- public String getRuntime() { return runtime; }
-
- @SuppressWarnings("unchecked")
- public static void main(String[] args) throws IOException {
- String json = JSONUtil.readFile("pig/src/main/resources/web/data/small-events.json");
- List<WorkflowEvent> events =
- (List<WorkflowEvent>)JSONUtil.readJson(json, new TypeReference<List<WorkflowEvent>>() { });
-// for (WorkflowEvent event : events) {
-// // useful if we need to read a file, add a field, output and re-generate
-// }
-
- JSONUtil.writeJson("pig/src/main/resources/web/data/small-events.json2", events);
- }
-}
Oops, something went wrong.

0 comments on commit d607c29

Please sign in to comment.