Skip to content

Commit

Permalink
Add support for attaching true timestamp for events (closes #196)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbeemster committed Jun 25, 2016
1 parent 25fe052 commit baf437c
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ private JSONObject assertPOSTRequest(RecordedRequest req) throws JSONException {
JSONObject payload = new JSONObject(req.getBody().readUtf8());
assertEquals(2, payload.length());
assertEquals(
"iglu:com.snowplowanalytics.snowplow/payload_data/jsonschema/1-0-3",
"iglu:com.snowplowanalytics.snowplow/payload_data/jsonschema/1-0-4",
payload.getString("schema")
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public void testExpectedForm() {
.label("some label")
.property("some property")
.value(123.56700)
.timestamp(123456789)
.deviceCreatedTimestamp(987654321)
.trueTimestamp(123456789)
.build();

data = structured.getPayload().getMap();
Expand All @@ -54,6 +57,8 @@ public void testExpectedForm() {
assertEquals("some label", data.get(Parameters.SE_LABEL));
assertEquals("some property", data.get(Parameters.SE_PROPERTY));
assertEquals("123.567", data.get(Parameters.SE_VALUE));
assertEquals("987654321", data.get(Parameters.DEVICE_TIMESTAMP));
assertEquals("123456789", data.get(Parameters.TRUE_TIMESTAMP));
}

public void testBuilderFailures() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ public void checkPostRequest(LinkedList<RecordedRequest> requests) throws Except
assertEquals("POST", request.getMethod());

JSONObject body = new JSONObject(request.getBody().readUtf8());
assertEquals("iglu:com.snowplowanalytics.snowplow/payload_data/jsonschema/1-0-3", body.getString("schema"));
assertEquals("iglu:com.snowplowanalytics.snowplow/payload_data/jsonschema/1-0-4", body.getString("schema"));

JSONArray data = body.getJSONArray("data");
for (int i = 0; i < data.length(); i++) {
Expand Down Expand Up @@ -345,29 +345,29 @@ public void checkUnstructuredEvent(JSONObject json) throws Exception {
public void trackPageView(Tracker tracker) throws Exception {
tracker.track(PageView.builder().pageUrl("pageUrl").pageTitle("pageTitle").referrer("pageReferrer").build());
tracker.track(PageView.builder().pageUrl("pageUrl").pageTitle("pageTitle").referrer("pageReferrer").customContext(getCustomContext()).build());
tracker.track(PageView.builder().pageUrl("pageUrl").pageTitle("pageTitle").referrer("pageReferrer").timestamp((long) 1433791172).build());
tracker.track(PageView.builder().pageUrl("pageUrl").pageTitle("pageTitle").referrer("pageReferrer").timestamp((long) 1433791172).customContext(getCustomContext()).build());
tracker.track(PageView.builder().pageUrl("pageUrl").pageTitle("pageTitle").referrer("pageReferrer").deviceCreatedTimestamp((long) 1433791172).build());
tracker.track(PageView.builder().pageUrl("pageUrl").pageTitle("pageTitle").referrer("pageReferrer").deviceCreatedTimestamp((long) 1433791172).customContext(getCustomContext()).build());
}

public void trackStructuredEvent(Tracker tracker) throws Exception {
tracker.track(Structured.builder().category("category").action("action").label("label").property("property").value(0.00).build());
tracker.track(Structured.builder().category("category").action("action").label("label").property("property").value(0.00).customContext(getCustomContext()).build());
tracker.track(Structured.builder().category("category").action("action").label("label").property("property").value(0.00).timestamp((long) 1433791172).build());
tracker.track(Structured.builder().category("category").action("action").label("label").property("property").value(0.00).timestamp((long) 1433791172).customContext(getCustomContext()).build());
tracker.track(Structured.builder().category("category").action("action").label("label").property("property").value(0.00).deviceCreatedTimestamp((long) 1433791172).build());
tracker.track(Structured.builder().category("category").action("action").label("label").property("property").value(0.00).deviceCreatedTimestamp((long) 1433791172).customContext(getCustomContext()).build());
}

public void trackScreenView(Tracker tracker) throws Exception {
tracker.track(ScreenView.builder().name("screenName").id("screenId").build());
tracker.track(ScreenView.builder().name("screenName").id("screenId").customContext(getCustomContext()).build());
tracker.track(ScreenView.builder().name("screenName").id("screenId").timestamp((long) 1433791172).build());
tracker.track(ScreenView.builder().name("screenName").id("screenId").timestamp((long) 1433791172).customContext(getCustomContext()).build());
tracker.track(ScreenView.builder().name("screenName").id("screenId").deviceCreatedTimestamp((long) 1433791172).build());
tracker.track(ScreenView.builder().name("screenName").id("screenId").deviceCreatedTimestamp((long) 1433791172).customContext(getCustomContext()).build());
}

public void trackTimings(Tracker tracker) throws Exception {
tracker.track(Timing.builder().category("category").variable("variable").timing(1).label("label").build());
tracker.track(Timing.builder().category("category").variable("variable").timing(1).label("label").customContext(getCustomContext()).build());
tracker.track(Timing.builder().category("category").variable("variable").timing(1).label("label").timestamp((long) 1433791172).build());
tracker.track(Timing.builder().category("category").variable("variable").timing(1).label("label").timestamp((long) 1433791172).customContext(getCustomContext()).build());
tracker.track(Timing.builder().category("category").variable("variable").timing(1).label("label").deviceCreatedTimestamp((long) 1433791172).build());
tracker.track(Timing.builder().category("category").variable("variable").timing(1).label("label").deviceCreatedTimestamp((long) 1433791172).customContext(getCustomContext()).build());
}

public void trackUnstructuredEvent(Tracker tracker) throws Exception {
Expand All @@ -376,8 +376,8 @@ public void trackUnstructuredEvent(Tracker tracker) throws Exception {
SelfDescribingJson test = new SelfDescribingJson("iglu:com.snowplowanalytics.snowplow/test_sdj/jsonschema/1-0-1", attributes);
tracker.track(SelfDescribing.builder().eventData(test).build());
tracker.track(SelfDescribing.builder().eventData(test).customContext(getCustomContext()).build());
tracker.track(SelfDescribing.builder().eventData(test).timestamp((long) 1433791172).build());
tracker.track(SelfDescribing.builder().eventData(test).timestamp((long) 1433791172).customContext(getCustomContext()).build());
tracker.track(SelfDescribing.builder().eventData(test).deviceCreatedTimestamp((long) 1433791172).build());
tracker.track(SelfDescribing.builder().eventData(test).deviceCreatedTimestamp((long) 1433791172).customContext(getCustomContext()).build());
}

public void trackEcommerceEvent(Tracker tracker) throws Exception {
Expand All @@ -386,8 +386,8 @@ public void trackEcommerceEvent(Tracker tracker) throws Exception {
items.add(item);
tracker.track(EcommerceTransaction.builder().orderId("order-1").totalValue(42.50).affiliation("affiliation").taxValue(2.50).shipping(5.00).city("Sydney").state("NSW").country("Australia").currency("AUD").items(items).build());
tracker.track(EcommerceTransaction.builder().orderId("order-1").totalValue(42.50).affiliation("affiliation").taxValue(2.50).shipping(5.00).city("Sydney").state("NSW").country("Australia").currency("AUD").items(items).customContext(getCustomContext()).build());
tracker.track(EcommerceTransaction.builder().orderId("order-1").totalValue(42.50).affiliation("affiliation").taxValue(2.50).shipping(5.00).city("Sydney").state("NSW").country("Australia").currency("AUD").items(items).timestamp((long) 1433791172).build());
tracker.track(EcommerceTransaction.builder().orderId("order-1").totalValue(42.50).affiliation("affiliation").taxValue(2.50).shipping(5.00).city("Sydney").state("NSW").country("Australia").currency("AUD").items(items).timestamp((long) 1433791172).customContext(getCustomContext()).build());
tracker.track(EcommerceTransaction.builder().orderId("order-1").totalValue(42.50).affiliation("affiliation").taxValue(2.50).shipping(5.00).city("Sydney").state("NSW").country("Australia").currency("AUD").items(items).deviceCreatedTimestamp((long) 1433791172).build());
tracker.track(EcommerceTransaction.builder().orderId("order-1").totalValue(42.50).affiliation("affiliation").taxValue(2.50).shipping(5.00).city("Sydney").state("NSW").country("Australia").currency("AUD").items(items).deviceCreatedTimestamp((long) 1433791172).customContext(getCustomContext()).build());
}

public List<SelfDescribingJson> getCustomContext() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ public void run() {
// Track each item individually
EcommerceTransaction ecommerceTransaction = (EcommerceTransaction) event;
for(EcommerceTransactionItem item : ecommerceTransaction.getItems()) {
item.setTimestamp(ecommerceTransaction.getTimestamp());
item.setDeviceCreatedTimestamp(ecommerceTransaction.getDeviceCreatedTimestamp());
addEventPayload(item.getPayload(), item.getContext(), item.getEventId());
}
} else if (eClass.equals(SelfDescribing.class)) {
Expand All @@ -332,7 +332,7 @@ public void run() {
SelfDescribing selfDescribing = SelfDescribing.builder()
.eventData((SelfDescribingJson) event.getPayload())
.customContext(context)
.timestamp(event.getTimestamp())
.deviceCreatedTimestamp(event.getDeviceCreatedTimestamp())
.eventId(event.getEventId())
.build();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ public class Parameters {
public static final String DATA = "data";
public static final String EVENT = "e";
public static final String EID = "eid";
@Deprecated
public static final String TIMESTAMP = "dtm";
public static final String DEVICE_TIMESTAMP = "dtm";
public static final String TRUE_TIMESTAMP = "ttm";
public static final String SENT_TIMESTAMP = "stm";
public static final String TRACKER_VERSION = "tv";
public static final String APPID = "aid";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class TrackerConstants {
public static final String PROTOCOL_VENDOR = "com.snowplowanalytics.snowplow";
public static final String PROTOCOL_VERSION = "tp2";

public static final String SCHEMA_PAYLOAD_DATA = "iglu:com.snowplowanalytics.snowplow/payload_data/jsonschema/1-0-3";
public static final String SCHEMA_PAYLOAD_DATA = "iglu:com.snowplowanalytics.snowplow/payload_data/jsonschema/1-0-4";
public static final String SCHEMA_CONTEXTS = "iglu:com.snowplowanalytics.snowplow/contexts/jsonschema/1-0-1";
public static final String SCHEMA_UNSTRUCT_EVENT = "iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0";
public static final String SCHEMA_SCREEN_VIEW = "iglu:com.snowplowanalytics.snowplow/screen_view/jsonschema/1-0-0";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,16 @@
public abstract class AbstractEvent implements Event {

protected final List<SelfDescribingJson> context;
protected long timestamp;
protected final String eventId;
protected long deviceCreatedTimestamp;
private Long trueTimestamp;

public static abstract class Builder<T extends Builder<T>> {

private List<SelfDescribingJson> context = new LinkedList<>();
private long timestamp = System.currentTimeMillis();
private String eventId = Util.getEventId();
private long deviceCreatedTimestamp = System.currentTimeMillis();
private Long trueTimestamp = null;

protected abstract T self();

Expand All @@ -56,26 +58,51 @@ public T customContext(List<SelfDescribingJson> context) {
return self();
}

/**
* A custom eventId for the event.
*
* @param eventId the eventId
* @return itself
*/
public T eventId(String eventId) {
this.eventId = eventId;
return self();
}

/**
* A custom event timestamp.
*
* @param timestamp the event timestamp as
* unix epoch
* @return itself
*/
@Deprecated
public T timestamp(long timestamp) {
this.timestamp = timestamp;
this.deviceCreatedTimestamp = timestamp;
return self();
}

/**
* A custom eventId for the event.
* A custom event timestamp.
*
* @param eventId the eventId
* @param deviceCreatedTimestamp the event timestamp as
* unix epoch
* @return itself
*/
public T eventId(String eventId) {
this.eventId = eventId;
public T deviceCreatedTimestamp(long deviceCreatedTimestamp) {
this.deviceCreatedTimestamp = deviceCreatedTimestamp;
return self();
}

/**
* A custom event timestamp.
*
* @param trueTimestamp the true event timestamp as
* unix epoch
* @return itself
*/
public T trueTimestamp(long trueTimestamp) {
this.trueTimestamp = trueTimestamp;
return self();
}
}
Expand All @@ -88,7 +115,8 @@ protected AbstractEvent(Builder<?> builder) {
Preconditions.checkArgument(!builder.eventId.isEmpty(), "eventId cannot be empty");

this.context = builder.context;
this.timestamp = builder.timestamp;
this.deviceCreatedTimestamp = builder.deviceCreatedTimestamp;
this.trueTimestamp = builder.trueTimestamp;
this.eventId = builder.eventId;
}

Expand All @@ -104,8 +132,16 @@ public List<SelfDescribingJson> getContext() {
* @return the events timestamp
*/
@Override
public long getTimestamp() {
return this.timestamp;
public long getDeviceCreatedTimestamp() {
return this.deviceCreatedTimestamp;
}

/**
* @return the optional true events timestamp
*/
@Override
public long getTrueTimestamp() {
return this.trueTimestamp;
}

/**
Expand All @@ -130,7 +166,10 @@ public String getEventId() {
*/
protected TrackerPayload putDefaultParams(TrackerPayload payload) {
payload.add(Parameters.EID, getEventId());
payload.add(Parameters.TIMESTAMP, Long.toString(getTimestamp()));
payload.add(Parameters.DEVICE_TIMESTAMP, Long.toString(getDeviceCreatedTimestamp()));
if (this.trueTimestamp != null) {
payload.add(Parameters.TRUE_TIMESTAMP, Long.toString(getTrueTimestamp()));
}
return payload;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,10 @@ protected EcommerceTransactionItem(Builder<?> builder) {
}

/**
* @param timestamp the new timestamp
* @param deviceCreatedTimestamp the new timestamp
*/
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
public void setDeviceCreatedTimestamp(long deviceCreatedTimestamp) {
this.deviceCreatedTimestamp = deviceCreatedTimestamp;
}

/**
Expand All @@ -154,7 +154,7 @@ public void setTimestamp(long timestamp) {
public TrackerPayload getPayload() {
TrackerPayload payload = new TrackerPayload();
payload.add(Parameters.EVENT, TrackerConstants.EVENT_ECOMM_ITEM);
payload.add(Parameters.TIMESTAMP, Long.toString(this.timestamp));
payload.add(Parameters.DEVICE_TIMESTAMP, Long.toString(this.deviceCreatedTimestamp));
payload.add(Parameters.TI_ITEM_ID, this.itemId);
payload.add(Parameters.TI_ITEM_SKU, this.sku);
payload.add(Parameters.TI_ITEM_NAME, this.name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ public interface Event {
/**
* @return the events timestamp
*/
long getTimestamp();
long getDeviceCreatedTimestamp();

/**
* @return the optional true events timestamp
*/
long getTrueTimestamp();

/**
* @return the event id
Expand Down

0 comments on commit baf437c

Please sign in to comment.