diff --git a/build.gradle b/build.gradle
index 639091a3..8fea99c3 100644
--- a/build.gradle
+++ b/build.gradle
@@ -83,7 +83,6 @@ dependencies {
testCompileOnly 'junit:junit:4.13'
testRuntimeOnly 'org.junit.vintage:junit-vintage-engine'
- testImplementation 'org.hamcrest:hamcrest:2.2'
testImplementation 'com.squareup.okhttp3:mockwebserver:4.9.2'
}
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/Subject.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/Subject.java
index c61958e8..1b0ff8f3 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/Subject.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/Subject.java
@@ -21,6 +21,8 @@
/**
* An object for managing extra event decoration.
+ * All the properties are optional. However, the timezone is set by default,
+ * to that of the server.
*/
public class Subject {
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/Tracker.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/Tracker.java
index 8079ab9b..abf41b58 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/Tracker.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/Tracker.java
@@ -187,7 +187,7 @@ public DevicePlatform getPlatform() {
* @return the wrapper containing the Tracker parameters
*/
public TrackerParameters getParameters() {
- return this.parameters;
+ return parameters;
}
// --- Event Tracking Functions
@@ -195,21 +195,41 @@ public TrackerParameters getParameters() {
/**
* Handles tracking the different types of events that
* the Tracker can encounter.
+ * A TrackerPayload object - or more than one, in the case of eCommerceTransaction events -
+ * will be created from the Event. This is passed to the configured Emitter.
+ * If the event was successfully added to the Emitter buffer for sending,
+ * a list containing the payload's eventId string (a UUID) is returned.
+ * EcommerceTransactions will return all the relevant eventIds in the list.
+ * If the Emitter event buffer is full, the payload will be lost. In this case, this method
+ * returns a list containing null.
+ *
+ * Implementation note: As a side effect of adding a payload to the Emitter,
+ * it triggers an Emitter thread to emit a batch of events.
*
* @param event the event to track
+ * @return a list of eventIDs (UUIDs)
*/
- public void track(Event event) {
+ public List track(Event event) {
+ List results = new ArrayList<>();
// a list because Ecommerce events become multiple Payloads
List processedEvents = eventTypeSpecificPreProcessing(event);
for (Event processedEvent : processedEvents) {
- // Event ID (eid) and device_created_timestamp (dtm) are generated when the Event is initialised
+ // Event ID (eid) and device_created_timestamp (dtm) are generated when
+ // the TrackerPayload is created
TrackerPayload payload = (TrackerPayload) processedEvent.getPayload();
addTrackerParameters(payload);
addContext(processedEvent, payload);
addSubject(processedEvent, payload);
- this.emitter.add(payload);
+
+ boolean addedToBuffer = emitter.add(payload);
+ if (addedToBuffer) {
+ results.add(payload.getEventId());
+ } else {
+ results.add(null);
+ }
}
+ return results;
}
private List eventTypeSpecificPreProcessing(Event event) {
@@ -223,7 +243,7 @@ private List eventTypeSpecificPreProcessing(Event event) {
if (eventClass.equals(Unstructured.class)) {
// Need to set the Base64 rule for Unstructured events
final Unstructured unstructured = (Unstructured) event;
- unstructured.setBase64Encode(this.parameters.getBase64Encoded());
+ unstructured.setBase64Encode(parameters.getBase64Encoded());
eventList.add(unstructured);
} else if (eventClass.equals(EcommerceTransaction.class)) {
@@ -231,23 +251,19 @@ private List eventTypeSpecificPreProcessing(Event event) {
eventList.add(ecommerceTransaction);
// Track each item individually
- for (final EcommerceTransactionItem item : ecommerceTransaction.getItems()) {
- item.setDeviceCreatedTimestamp(ecommerceTransaction.getDeviceCreatedTimestamp());
- eventList.add(item);
- }
+ eventList.addAll(ecommerceTransaction.getItems());
+
} else if (eventClass.equals(Timing.class) || eventClass.equals(ScreenView.class)) {
// Timing and ScreenView events are wrapper classes for Unstructured events
// Need to create Unstructured events from them to send.
final Unstructured unstructured = Unstructured.builder()
.eventData((SelfDescribingJson) event.getPayload())
.customContext(event.getContext())
- .deviceCreatedTimestamp(event.getDeviceCreatedTimestamp())
.trueTimestamp(event.getTrueTimestamp())
- .eventId(event.getEventId())
.subject(event.getSubject())
.build();
- unstructured.setBase64Encode(this.parameters.getBase64Encoded());
+ unstructured.setBase64Encode(parameters.getBase64Encoded());
eventList.add(unstructured);
} else {
@@ -257,10 +273,10 @@ private List eventTypeSpecificPreProcessing(Event event) {
}
private void addTrackerParameters(TrackerPayload payload) {
- payload.add(Parameter.PLATFORM, this.parameters.getPlatform().toString());
- payload.add(Parameter.APP_ID, this.parameters.getAppId());
- payload.add(Parameter.NAMESPACE, this.parameters.getNamespace());
- payload.add(Parameter.TRACKER_VERSION, this.parameters.getTrackerVersion());
+ payload.add(Parameter.PLATFORM, parameters.getPlatform().toString());
+ payload.add(Parameter.APP_ID, parameters.getAppId());
+ payload.add(Parameter.NAMESPACE, parameters.getNamespace());
+ payload.add(Parameter.TRACKER_VERSION, parameters.getTrackerVersion());
}
private void addContext(Event event, TrackerPayload payload) {
@@ -269,7 +285,7 @@ private void addContext(Event event, TrackerPayload payload) {
// Build the final context and add it to the payload
if (entities != null && entities.size() > 0) {
SelfDescribingJson envelope = getFinalContext(entities);
- payload.addMap(envelope.getMap(), this.parameters.getBase64Encoded(), Parameter.CONTEXT_ENCODED, Parameter.CONTEXT);
+ payload.addMap(envelope.getMap(), parameters.getBase64Encoded(), Parameter.CONTEXT_ENCODED, Parameter.CONTEXT);
}
}
@@ -293,8 +309,8 @@ private void addSubject(Event event, TrackerPayload payload) {
// Add subject if available
if (eventSubject != null) {
payload.addMap(new HashMap<>(eventSubject.getSubject()));
- } else if (this.subject != null) {
- payload.addMap(new HashMap<>(this.subject.getSubject()));
+ } else if (subject != null) {
+ payload.addMap(new HashMap<>(subject.getSubject()));
}
}
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/AbstractEmitter.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/AbstractEmitter.java
index e56e4c14..00779196 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/AbstractEmitter.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/AbstractEmitter.java
@@ -133,7 +133,7 @@ protected AbstractEmitter(final Builder> builder) {
* @param payload an payload
*/
@Override
- public abstract void add(TrackerPayload payload);
+ public abstract boolean add(TrackerPayload payload);
/**
* Customize the emitter batch size to any valid integer greater than zero.
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/BatchEmitter.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/BatchEmitter.java
index c76951eb..c13ea4fe 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/BatchEmitter.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/BatchEmitter.java
@@ -108,13 +108,12 @@ protected BatchEmitter(final Builder> builder) {
/**
* Adds a TrackerPayload to the concurrent queue buffer
*
- * Implementation note: Be aware that calling `close()` on a BatchEmitter instance
- * has a side-effect and will shutdown that ExecutorService.
+ * Implementation note: As a side effect it triggers an Emitter thread to emit a batch of events.
*
* @param payload a payload
*/
@Override
- public void add(final TrackerPayload payload) {
+ public boolean add(final TrackerPayload payload) {
boolean result = eventStore.addEvent(payload);
if (!isClosing) {
@@ -126,6 +125,8 @@ public void add(final TrackerPayload payload) {
if (!result) {
LOGGER.error("Unable to add payload to emitter, emitter buffer is full");
}
+
+ return result;
}
/**
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/Emitter.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/Emitter.java
index aac70315..c9cb9b50 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/Emitter.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/Emitter.java
@@ -27,7 +27,7 @@ public interface Emitter {
*
* @param payload a payload to be emitted
*/
- void add(TrackerPayload payload);
+ boolean add(TrackerPayload payload);
/**
* Customize the emitter batch size to any valid integer
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/SimpleEmitter.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/SimpleEmitter.java
index 715da53b..a6cd3bf8 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/SimpleEmitter.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/emitter/SimpleEmitter.java
@@ -56,8 +56,12 @@ protected SimpleEmitter(final Builder> builder) {
* @param payload a payload
*/
@Override
- public void add(TrackerPayload payload) {
+ public boolean add(TrackerPayload payload) {
executor.execute(getGetRequestRunnable(payload));
+
+ // This result doesn't mean anything
+ // The return type is for BatchEmitter's benefit
+ return true;
}
/**
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/AbstractEvent.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/AbstractEvent.java
index 92bb8988..369bb3a1 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/AbstractEvent.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/AbstractEvent.java
@@ -40,22 +40,16 @@ public abstract class AbstractEvent implements Event {
protected final List context;
- protected long deviceCreatedTimestamp;
-
/**
* The true timestamp may be null if none is set.
*/
protected Long trueTimestamp;
-
- protected final String eventId;
protected final Subject subject;
public static abstract class Builder> {
private List context = new LinkedList<>();
- private long deviceCreatedTimestamp = System.currentTimeMillis();
protected Long trueTimestamp = null;
- private String eventId = Utils.getEventId();
private Subject subject = null;
protected abstract T self();
@@ -71,31 +65,6 @@ public T customContext(List context) {
return self();
}
- /**
- * A custom event timestamp.
- *
- * @param timestamp the event timestamp as
- * unix epoch
- * @return itself
- * Use {@link #trueTimestamp} or {@link #deviceCreatedTimestamp}
- */
- @Deprecated
- public T timestamp(long timestamp) {
- return deviceCreatedTimestamp(timestamp);
- }
-
- /**
- * Adjust the device-created timestamp. This is usually not what you want, check {@link #trueTimestamp}.
- *
- * @param timestamp the event timestamp as
- * unix epoch
- * @return itself
- */
- public T deviceCreatedTimestamp(long timestamp) {
- this.deviceCreatedTimestamp = timestamp;
- return self();
- }
-
/**
* The true timestamp of that event (as determined by the user).
*
@@ -108,17 +77,6 @@ public T trueTimestamp(Long timestamp) {
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 subject for the event.
*
@@ -146,13 +104,9 @@ protected AbstractEvent(Builder> builder) {
// Precondition checks
Preconditions.checkNotNull(builder.context);
- Preconditions.checkNotNull(builder.eventId);
- Preconditions.checkArgument(!builder.eventId.isEmpty(), "eventId cannot be empty");
this.context = builder.context;
- this.deviceCreatedTimestamp = builder.deviceCreatedTimestamp;
this.trueTimestamp = builder.trueTimestamp;
- this.eventId = builder.eventId;
this.subject = builder.subject;
}
@@ -164,23 +118,6 @@ public List getContext() {
return new ArrayList<>(this.context);
}
- /**
- * @return the event's timestamp
- * @deprecated Use {@link #getTrueTimestamp()} or {@link #getDeviceCreatedTimestamp()}
- */
- @Override
- public long getTimestamp() {
- return this.deviceCreatedTimestamp;
- }
-
- /**
- * @return the event's device created timestamp.
- */
- @Override
- public long getDeviceCreatedTimestamp() {
- return deviceCreatedTimestamp;
- }
-
/**
* @return the event's true timestamp.
*/
@@ -189,14 +126,6 @@ public Long getTrueTimestamp() {
return trueTimestamp;
}
- /**
- * @return the event id
- */
- @Override
- public String getEventId() {
- return this.eventId;
- }
-
/**
* @return the event subject
*/
@@ -217,12 +146,10 @@ public Subject getSubject() {
* @param payload the payload to add to.
* @return the TrackerPayload with appended values.
*/
- protected TrackerPayload putDefaultParams(TrackerPayload payload) {
- payload.add(Parameter.EID, getEventId());
- if (getTrueTimestamp()!=null) {
+ protected TrackerPayload putTrueTimestamp(TrackerPayload payload) {
+ if (getTrueTimestamp() != null) {
payload.add(Parameter.TRUE_TIMESTAMP, Long.toString(getTrueTimestamp()));
}
- payload.add(Parameter.DEVICE_CREATED_TIMESTAMP, Long.toString(getDeviceCreatedTimestamp()));
return payload;
}
}
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/EcommerceTransaction.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/EcommerceTransaction.java
index d7f31752..9151e014 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/EcommerceTransaction.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/EcommerceTransaction.java
@@ -209,7 +209,7 @@ public TrackerPayload getPayload() {
payload.add(Parameter.TR_STATE, this.state);
payload.add(Parameter.TR_COUNTRY, this.country);
payload.add(Parameter.TR_CURRENCY, this.currency);
- return putDefaultParams(payload);
+ return putTrueTimestamp(payload);
}
/**
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/EcommerceTransactionItem.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/EcommerceTransactionItem.java
index 0a928f4c..37a89cbc 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/EcommerceTransactionItem.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/EcommerceTransactionItem.java
@@ -140,15 +140,6 @@ protected EcommerceTransactionItem(Builder> builder) {
this.currency = builder.currency;
}
- /**
- * @param timestamp the new timestamp
- * Use {@link #setTrueTimestamp(long)} or {@link #setTrueTimestamp(long)}
- */
- @Deprecated
- public void setTimestamp(long timestamp) {
- setDeviceCreatedTimestamp(timestamp);
- }
-
/**
* @param timestamp the new timestamp
*/
@@ -156,13 +147,6 @@ public void setTrueTimestamp(long timestamp) {
this.trueTimestamp = timestamp;
}
- /**
- * @param timestamp the new timestamp
- */
- public void setDeviceCreatedTimestamp(Long timestamp) {
- this.deviceCreatedTimestamp = timestamp;
- }
-
/**
* Returns a TrackerPayload which can be stored into
* the local database.
@@ -179,6 +163,6 @@ public TrackerPayload getPayload() {
payload.add(Parameter.TI_ITEM_PRICE, Double.toString(this.price));
payload.add(Parameter.TI_ITEM_QUANTITY, Integer.toString(this.quantity));
payload.add(Parameter.TI_ITEM_CURRENCY, this.currency);
- return putDefaultParams(payload);
+ return putTrueTimestamp(payload);
}
}
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/Event.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/Event.java
index 935279a1..b9909913 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/Event.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/Event.java
@@ -28,28 +28,11 @@ public interface Event {
*/
List getContext();
- /**
- * @return the event's timestamp
- * Use {@link #getTrueTimestamp()} or {@link #getDeviceCreatedTimestamp()}
- */
- @Deprecated
- long getTimestamp();
-
/**
* @return the event's true timestamp
*/
Long getTrueTimestamp();
- /**
- * @return the event's device created timestamp
- */
- long getDeviceCreatedTimestamp();
-
- /**
- * @return the event id
- */
- String getEventId();
-
/**
* @return the event subject
*/
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/PageView.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/PageView.java
index 27bed72f..87da01f4 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/PageView.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/PageView.java
@@ -102,6 +102,6 @@ public TrackerPayload getPayload() {
payload.add(Parameter.PAGE_URL, this.pageUrl);
payload.add(Parameter.PAGE_TITLE, this.pageTitle);
payload.add(Parameter.PAGE_REFR, this.referrer);
- return putDefaultParams(payload);
+ return putTrueTimestamp(payload);
}
}
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/ScreenView.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/ScreenView.java
index d84adc57..9b1bf1a0 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/ScreenView.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/ScreenView.java
@@ -19,6 +19,8 @@
import com.snowplowanalytics.snowplow.tracker.payload.SelfDescribingJson;
import com.snowplowanalytics.snowplow.tracker.payload.TrackerPayload;
+import java.util.LinkedHashMap;
+
public class ScreenView extends AbstractEvent {
private final String name;
@@ -79,9 +81,9 @@ protected ScreenView(Builder> builder) {
* @return the payload as a SelfDescribingJson.
*/
public SelfDescribingJson getPayload() {
- TrackerPayload payload = new TrackerPayload();
- payload.add(Parameter.SV_ID, this.id);
- payload.add(Parameter.SV_NAME, this.name);
+ LinkedHashMap payload = new LinkedHashMap<>();
+ payload.put(Parameter.SV_ID, this.id);
+ payload.put(Parameter.SV_NAME, this.name);
return new SelfDescribingJson(Constants.SCHEMA_SCREEN_VIEW, payload);
}
}
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/Structured.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/Structured.java
index e80da843..06e7f282 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/Structured.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/Structured.java
@@ -131,6 +131,6 @@ public TrackerPayload getPayload() {
payload.add(Parameter.SE_PROPERTY, this.property);
payload.add(Parameter.SE_VALUE,
this.value != null ? Double.toString(this.value) : null);
- return putDefaultParams(payload);
+ return putTrueTimestamp(payload);
}
}
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/Unstructured.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/Unstructured.java
index a73b4575..37174422 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/events/Unstructured.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/events/Unstructured.java
@@ -89,6 +89,6 @@ public TrackerPayload getPayload() {
payload.add(Parameter.EVENT, Constants.EVENT_UNSTRUCTURED);
payload.addMap(envelope.getMap(), this.base64Encode,
Parameter.UNSTRUCTURED_ENCODED, Parameter.UNSTRUCTURED);
- return putDefaultParams(payload);
+ return putTrueTimestamp(payload);
}
}
diff --git a/src/main/java/com/snowplowanalytics/snowplow/tracker/payload/TrackerPayload.java b/src/main/java/com/snowplowanalytics/snowplow/tracker/payload/TrackerPayload.java
index 93bb9303..21af7f98 100644
--- a/src/main/java/com/snowplowanalytics/snowplow/tracker/payload/TrackerPayload.java
+++ b/src/main/java/com/snowplowanalytics/snowplow/tracker/payload/TrackerPayload.java
@@ -16,6 +16,7 @@
import java.util.LinkedHashMap;
import java.util.Map;
+import com.snowplowanalytics.snowplow.tracker.constants.Parameter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -29,6 +30,25 @@ public class TrackerPayload implements Payload {
private static final Logger LOGGER = LoggerFactory.getLogger(TrackerPayload.class);
protected final Map payload = new LinkedHashMap<>();
+ private final String eventId;
+ private final Long deviceCreatedTimestamp;
+
+
+ public TrackerPayload() {
+ eventId = Utils.getEventId();
+ deviceCreatedTimestamp = System.currentTimeMillis();
+
+ add(Parameter.EID, eventId);
+ add(Parameter.DEVICE_CREATED_TIMESTAMP, Long.toString(deviceCreatedTimestamp));
+ }
+
+ public String getEventId() {
+ return eventId;
+ }
+
+ public Long getDeviceCreatedTimestamp() {
+ return deviceCreatedTimestamp;
+ }
/**
* Add a key-value pair to the payload: - Checks that the key is not null or
diff --git a/src/test/java/com/snowplowanalytics/snowplow/tracker/TrackerTest.java b/src/test/java/com/snowplowanalytics/snowplow/tracker/TrackerTest.java
index b2840266..8b922cc0 100644
--- a/src/test/java/com/snowplowanalytics/snowplow/tracker/TrackerTest.java
+++ b/src/test/java/com/snowplowanalytics/snowplow/tracker/TrackerTest.java
@@ -15,8 +15,6 @@
import java.util.*;
import static java.util.Collections.singletonList;
-import com.snowplowanalytics.snowplow.tracker.emitter.BatchPayload;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -31,31 +29,23 @@
public class TrackerTest {
public static final String EXPECTED_CONTEXTS = "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/contexts/jsonschema/1-0-1\",\"data\":[{\"schema\":\"schema\",\"data\":{\"foo\":\"bar\"}}]}";
- public static final String EXPECTED_EVENT_ID = "15e9b149-6029-4f6e-8447-5b9797c9e6be";
public static class MockEmitter implements Emitter {
public ArrayList eventList = new ArrayList<>();
@Override
- public void add(TrackerPayload payload) {
+ public boolean add(TrackerPayload payload) {
eventList.add(payload);
+ return true;
}
-
@Override
public void setBatchSize(int batchSize) {}
-
@Override
public void flushBuffer() {}
-
@Override
- public int getBatchSize() {
- return 0;
- }
-
+ public int getBatchSize() { return 0; }
@Override
- public List getBuffer() {
- return null;
- }
+ public List getBuffer() { return null; }
}
MockEmitter mockEmitter;
@@ -75,6 +65,57 @@ public void setUp() {
// --- Event Tests
+ @Test
+ public void testTrackReturnsEventIdIfSuccessful() throws InterruptedException {
+ // a list to allow for eCommerceTransaction
+ List result = tracker.track(Unstructured.builder()
+ .eventData(new SelfDescribingJson(
+ "iglu:com.snowplowanalytics.snowplow/example/jsonschema/1-0-0",
+ ImmutableMap.of("foo", "bar")
+ ))
+ .build());
+
+ Thread.sleep(500);
+
+ boolean isValidEventId = true;
+ try {
+ UUID.fromString(result.get(0));
+ } catch (Exception e) {
+ isValidEventId = false;
+ }
+
+ assertTrue(isValidEventId);
+ }
+
+ @Test
+ public void testTrackReturnsNullIfEventWasDropped() throws InterruptedException {
+ class FailingMockEmitter implements Emitter {
+ @Override
+ public boolean add(TrackerPayload payload) { return false; }
+ @Override
+ public void setBatchSize(int batchSize) {}
+ @Override
+ public void flushBuffer() {}
+ @Override
+ public int getBatchSize() { return 0; }
+ @Override
+ public List getBuffer() { return null; }
+ }
+ FailingMockEmitter failingMockEmitter = new FailingMockEmitter();
+ tracker = new Tracker.TrackerBuilder(failingMockEmitter, "AF003", "cloudfront").build();
+
+ List result = tracker.track(Unstructured.builder()
+ .eventData(new SelfDescribingJson(
+ "iglu:com.snowplowanalytics.snowplow/example/jsonschema/1-0-0",
+ ImmutableMap.of("foo", "bar")
+ ))
+ .build());
+
+ Thread.sleep(500);
+
+ assertNull(result.get(0));
+ }
+
@Test
public void testEcommerceEvent() throws InterruptedException {
// Given
@@ -87,9 +128,7 @@ public void testEcommerceEvent() throws InterruptedException {
.category("category")
.currency("currency")
.customContext(contexts)
- .deviceCreatedTimestamp(123456)
.trueTimestamp(456789L)
- .eventId(EXPECTED_EVENT_ID)
.build();
// When
@@ -105,9 +144,7 @@ public void testEcommerceEvent() throws InterruptedException {
.currency("currency")
.items(item)
.customContext(contexts)
- .deviceCreatedTimestamp(123456)
.trueTimestamp(456789L)
- .eventId(EXPECTED_EVENT_ID)
.build());
// Then
@@ -117,15 +154,13 @@ public void testEcommerceEvent() throws InterruptedException {
assertEquals(2, results.size());
Map result1 = results.get(0).getMap();
- assertEquals(ImmutableMap.builder()
+ Map expected1 = ImmutableMap.builder()
.put("e", "tr")
.put("tr_cu", "currency")
.put("co", EXPECTED_CONTEXTS)
- .put("eid", EXPECTED_EVENT_ID)
.put("tna", "AF003")
.put("aid", "cloudfront")
.put("tr_sh", "3.0")
- .put("dtm", "123456")
.put("ttm", "456789")
.put("tz", "Etc/UTC")
.put("tr_co", "country")
@@ -137,19 +172,19 @@ public void testEcommerceEvent() throws InterruptedException {
.put("tr_tt", "1.0")
.put("tr_ci", "city")
.put("tr_st", "state")
- .build(), result1);
+ .build();
+
+ assertTrue(result1.entrySet().containsAll(expected1.entrySet()));
Map result2 = results.get(1).getMap();
- assertEquals(ImmutableMap.builder()
+ Map expected2 = ImmutableMap.builder()
.put("ti_nm", "name")
.put("ti_id", "order_id")
.put("e", "ti")
.put("co", EXPECTED_CONTEXTS)
- .put("eid", EXPECTED_EVENT_ID)
.put("tna", "AF003")
.put("aid", "cloudfront")
.put("ti_cu", "currency")
- .put("dtm", "123456")
.put("ttm", "456789")
.put("tz", "Etc/UTC")
.put("ti_pr", "1.0")
@@ -158,7 +193,9 @@ public void testEcommerceEvent() throws InterruptedException {
.put("tv", Version.TRACKER)
.put("ti_ca", "category")
.put("ti_sk", "sku")
- .build(), result2);
+ .build();
+
+ assertTrue(result2.entrySet().containsAll(expected2.entrySet()));
}
@Test
@@ -166,32 +203,30 @@ public void testUnstructuredEventWithContext() throws InterruptedException {
// When
tracker.track(Unstructured.builder()
.eventData(new SelfDescribingJson(
- "payload",
+ "iglu:com.snowplowanalytics.snowplow/example/jsonschema/1-0-0",
ImmutableMap.of("foo", "bar")
))
.customContext(contexts)
- .deviceCreatedTimestamp(123456)
.trueTimestamp(456789L)
- .eventId(EXPECTED_EVENT_ID)
.build());
// Then
Thread.sleep(500);
Map result = mockEmitter.eventList.get(0).getMap();
- assertEquals(ImmutableMap.builder()
+ Map expected = ImmutableMap.builder()
.put("p", "srv")
.put("tv", Version.TRACKER)
.put("e", "ue")
.put("co", EXPECTED_CONTEXTS)
- .put("eid", EXPECTED_EVENT_ID)
.put("tna", "AF003")
.put("tz", "Etc/UTC")
- .put("ue_pr", "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"schema\":\"payload\",\"data\":{\"foo\":\"bar\"}}}")
- .put("dtm", "123456")
+ .put("ue_pr", "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"schema\":\"iglu:com.snowplowanalytics.snowplow/example/jsonschema/1-0-0\",\"data\":{\"foo\":\"bar\"}}}")
.put("ttm", "456789")
.put("aid", "cloudfront")
- .build(), result);
+ .build();
+
+ assertTrue(result.entrySet().containsAll(expected.entrySet()));
}
@Test
@@ -199,30 +234,28 @@ public void testUnstructuredEventWithoutContext() throws InterruptedException {
// When
tracker.track(Unstructured.builder()
.eventData(new SelfDescribingJson(
- "payload",
+ "iglu:com.snowplowanalytics.snowplow/example/jsonschema/1-0-0",
ImmutableMap.of("foo", "baær")
))
- .deviceCreatedTimestamp(123456)
.trueTimestamp(456789L)
- .eventId(EXPECTED_EVENT_ID)
.build());
// Then
Thread.sleep(500);
Map result = mockEmitter.eventList.get(0).getMap();
- assertEquals(ImmutableMap.builder()
+ Map expected = ImmutableMap.builder()
.put("p", "srv")
.put("tv", Version.TRACKER)
- .put("eid", EXPECTED_EVENT_ID)
.put("e", "ue")
.put("tna", "AF003")
.put("tz", "Etc/UTC")
- .put("ue_pr", "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"schema\":\"payload\",\"data\":{\"foo\":\"baær\"}}}")
- .put("dtm", "123456")
+ .put("ue_pr", "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"schema\":\"iglu:com.snowplowanalytics.snowplow/example/jsonschema/1-0-0\",\"data\":{\"foo\":\"baær\"}}}")
.put("ttm", "456789")
.put("aid", "cloudfront")
- .build(), result);
+ .build();
+
+ assertTrue(result.entrySet().containsAll(expected.entrySet()));
}
@Test
@@ -230,33 +263,31 @@ public void testUnstructuredEventWithoutTrueTimestamp() throws InterruptedExcept
// When
tracker.track(Unstructured.builder()
.eventData(new SelfDescribingJson(
- "payload",
- ImmutableMap.of("foo", "baær")
+ "iglu:com.snowplowanalytics.snowplow/example/jsonschema/1-0-0",
+ ImmutableMap.of("foo", "bar")
))
- .deviceCreatedTimestamp(123456)
- .eventId(EXPECTED_EVENT_ID)
.build());
// Then
Thread.sleep(500);
Map result = mockEmitter.eventList.get(0).getMap();
- assertEquals(ImmutableMap.builder()
+ Map expected = ImmutableMap.builder()
.put("p", "srv")
.put("tv", Version.TRACKER)
- .put("eid", EXPECTED_EVENT_ID)
.put("e", "ue")
.put("tna", "AF003")
.put("tz", "Etc/UTC")
- .put("ue_pr", "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"schema\":\"payload\",\"data\":{\"foo\":\"baær\"}}}")
- .put("dtm", "123456")
+ .put("ue_pr", "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"schema\":\"iglu:com.snowplowanalytics.snowplow/example/jsonschema/1-0-0\",\"data\":{\"foo\":\"baær\"}}}")
.put("aid", "cloudfront")
- .build(), result);
+ .build();
+
+ assertTrue(result.entrySet().containsAll(expected.entrySet()));
}
@Test
public void testTrackPageView() throws InterruptedException {
- tracker = new Tracker.TrackerBuilder(this.mockEmitter, "AF003", "cloudfront")
+ tracker = new Tracker.TrackerBuilder(mockEmitter, "AF003", "cloudfront")
.subject(new Subject.SubjectBuilder().build())
.base64(false)
.build();
@@ -268,17 +299,14 @@ public void testTrackPageView() throws InterruptedException {
.pageTitle("title")
.referrer("referer")
.customContext(contexts)
- .deviceCreatedTimestamp(123456)
.trueTimestamp(456789L)
- .eventId(EXPECTED_EVENT_ID)
.build());
// Then
Thread.sleep(500);
Map result = mockEmitter.eventList.get(0).getMap();
- assertEquals(ImmutableMap.builder()
- .put("dtm", "123456")
+ Map expected = ImmutableMap.builder()
.put("ttm", "456789")
.put("tz", "Etc/UTC")
.put("e", "pv")
@@ -286,12 +314,13 @@ public void testTrackPageView() throws InterruptedException {
.put("tv", Version.TRACKER)
.put("p", "srv")
.put("co", EXPECTED_CONTEXTS)
- .put("eid", EXPECTED_EVENT_ID)
.put("tna", "AF003")
.put("aid", "cloudfront")
.put("refr", "referer")
.put("url", "url")
- .build(), result);
+ .build();
+
+ assertTrue(result.entrySet().containsAll(expected.entrySet()));
}
@Test
@@ -301,20 +330,15 @@ public void testTrackTwoEvents() throws InterruptedException {
.pageUrl("url")
.pageTitle("title")
.referrer("referer")
- .deviceCreatedTimestamp(123456)
- .trueTimestamp(456789L)
- .eventId("9783090a-dace-4c85-a75c-933b4596a6c5")
+ .trueTimestamp(123456L)
.build());
- Thread.sleep(500);
-
- tracker.track(PageView.builder()
- .pageUrl("url")
- .pageTitle("title")
- .referrer("referer")
- .deviceCreatedTimestamp(123456)
+ tracker.track(Unstructured.builder()
+ .eventData(new SelfDescribingJson(
+ "iglu:com.snowplowanalytics.snowplow/example/jsonschema/1-0-0",
+ ImmutableMap.of("foo", "bar")
+ ))
.trueTimestamp(456789L)
- .eventId("39139d43-ea13-4163-8559-adea258bf9c4")
.build());
// Then
@@ -324,36 +348,34 @@ public void testTrackTwoEvents() throws InterruptedException {
assertEquals(2, results.size());
Map result1 = results.get(0).getMap();
- assertEquals(ImmutableMap.builder()
- .put("dtm", "123456")
- .put("ttm", "456789")
+ Map expected1 = ImmutableMap.builder()
+ .put("ttm", "123456")
.put("tz", "Etc/UTC")
.put("e", "pv")
.put("page", "title")
.put("tv", Version.TRACKER)
.put("p", "srv")
- .put("eid", "9783090a-dace-4c85-a75c-933b4596a6c5")
.put("tna", "AF003")
.put("aid", "cloudfront")
.put("refr", "referer")
.put("url", "url")
- .build(), result1);
+ .build();
+
+ assertTrue(result1.entrySet().containsAll(expected1.entrySet()));
Map result2 = results.get(1).getMap();
- assertEquals(ImmutableMap.builder()
- .put("dtm", "123456")
+ Map expected2 = ImmutableMap.builder()
.put("ttm", "456789")
- .put("tz", "Etc/UTC")
- .put("e", "pv")
- .put("page", "title")
- .put("tv", Version.TRACKER)
.put("p", "srv")
- .put("eid", "39139d43-ea13-4163-8559-adea258bf9c4")
+ .put("tv", Version.TRACKER)
+ .put("e", "ue")
.put("tna", "AF003")
+ .put("tz", "Etc/UTC")
+ .put("ue_pr", "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"schema\":\"iglu:com.snowplowanalytics.snowplow/example/jsonschema/1-0-0\",\"data\":{\"foo\":\"bar\"}}}")
.put("aid", "cloudfront")
- .put("refr", "referer")
- .put("url", "url")
- .build(), result2);
+ .build();
+
+ assertTrue(result2.entrySet().containsAll(expected2.entrySet()));
}
@Test
@@ -363,28 +385,26 @@ public void testTrackScreenView() throws InterruptedException {
.name("name")
.id("id")
.customContext(contexts)
- .deviceCreatedTimestamp(123456)
.trueTimestamp(456789L)
- .eventId(EXPECTED_EVENT_ID)
.build());
// Then
Thread.sleep(500);
Map result = mockEmitter.eventList.get(0).getMap();
- assertEquals(ImmutableMap.builder()
- .put("dtm", "123456")
+ Map expected = ImmutableMap.builder()
.put("ttm", "456789")
.put("tz", "Etc/UTC")
.put("e", "ue")
.put("tv", Version.TRACKER)
.put("p", "srv")
.put("co", EXPECTED_CONTEXTS)
- .put("eid", EXPECTED_EVENT_ID)
.put("tna", "AF003")
.put("aid", "cloudfront")
.put("ue_pr", "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"schema\":\"iglu:com.snowplowanalytics.snowplow/screen_view/jsonschema/1-0-0\",\"data\":{\"id\":\"id\",\"name\":\"name\"}}}")
- .build(), result);
+ .build();
+
+ assertTrue(result.entrySet().containsAll(expected.entrySet()));
}
@Test
@@ -393,27 +413,25 @@ public void testTrackScreenViewWithTimestamp() throws InterruptedException {
tracker.track(ScreenView.builder()
.name("name")
.id("id")
- .deviceCreatedTimestamp(123456)
.trueTimestamp(456789L)
- .eventId(EXPECTED_EVENT_ID)
.build());
// Then
Thread.sleep(500);
Map result = mockEmitter.eventList.get(0).getMap();
- assertEquals(ImmutableMap.builder()
- .put("dtm", "123456")
+ Map expected = ImmutableMap.builder()
.put("ttm", "456789")
.put("tz", "Etc/UTC")
.put("e", "ue")
.put("tv", Version.TRACKER)
.put("p", "srv")
- .put("eid", EXPECTED_EVENT_ID)
.put("tna", "AF003")
.put("aid", "cloudfront")
.put("ue_pr", "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"schema\":\"iglu:com.snowplowanalytics.snowplow/screen_view/jsonschema/1-0-0\",\"data\":{\"id\":\"id\",\"name\":\"name\"}}}")
- .build(), result);
+ .build();
+
+ assertTrue(result.entrySet().containsAll(expected.entrySet()));
}
@Test
@@ -423,28 +441,26 @@ public void testTrackScreenViewWithDefaultContextAndTimestamp() throws Interrupt
.name("name")
.id("id")
.customContext(contexts)
- .deviceCreatedTimestamp(123456)
.trueTimestamp(456789L)
- .eventId(EXPECTED_EVENT_ID)
.build());
// Then
Thread.sleep(500);
Map result = mockEmitter.eventList.get(0).getMap();
- assertEquals(ImmutableMap.builder()
+ Map expected = ImmutableMap.builder()
.put("p", "srv")
.put("tv", Version.TRACKER)
.put("e", "ue")
.put("co", EXPECTED_CONTEXTS)
- .put("eid", EXPECTED_EVENT_ID)
.put("tna", "AF003")
.put("tz", "Etc/UTC")
.put("ue_pr", "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"schema\":\"iglu:com.snowplowanalytics.snowplow/screen_view/jsonschema/1-0-0\",\"data\":{\"id\":\"id\",\"name\":\"name\"}}}")
- .put("dtm", "123456")
.put("ttm", "456789")
.put("aid", "cloudfront")
- .build(), result);
+ .build();
+
+ assertTrue(result.entrySet().containsAll(expected.entrySet()));
}
@Test
@@ -456,28 +472,26 @@ public void testTrackTiming() throws InterruptedException {
.variable("variable")
.timing(10)
.customContext(contexts)
- .deviceCreatedTimestamp(123456)
.trueTimestamp(456789L)
- .eventId(EXPECTED_EVENT_ID)
.build());
// Then
Thread.sleep(500);
Map result = mockEmitter.eventList.get(0).getMap();
- assertEquals(ImmutableMap.builder()
+ Map expected = ImmutableMap.builder()
.put("p", "srv")
.put("tv", Version.TRACKER)
.put("e", "ue")
.put("co", EXPECTED_CONTEXTS)
- .put("eid", EXPECTED_EVENT_ID)
.put("tna", "AF003")
.put("tz", "Etc/UTC")
.put("ue_pr", "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"schema\":\"iglu:com.snowplowanalytics.snowplow/timing/jsonschema/1-0-0\",\"data\":{\"category\":\"category\",\"label\":\"label\",\"timing\":10,\"variable\":\"variable\"}}}")
- .put("dtm", "123456")
.put("ttm", "456789")
.put("aid", "cloudfront")
- .build(), result);
+ .build();
+
+ assertTrue(result.entrySet().containsAll(expected.entrySet()));
}
@Test
@@ -494,9 +508,7 @@ public void testTrackTimingWithSubject() throws InterruptedException {
.variable("variable")
.timing(10)
.customContext(contexts)
- .deviceCreatedTimestamp(123456)
.trueTimestamp(456789L)
- .eventId(EXPECTED_EVENT_ID)
.subject(s1)
.build());
@@ -504,20 +516,21 @@ public void testTrackTimingWithSubject() throws InterruptedException {
Thread.sleep(500);
Map result = mockEmitter.eventList.get(0).getMap();
- assertEquals(ImmutableMap.builder()
+ Map expected = ImmutableMap.builder()
.put("p", "srv")
.put("ue_pr", "{\"schema\":\"iglu:com.snowplowanalytics.snowplow/unstruct_event/jsonschema/1-0-0\",\"data\":{\"schema\":\"iglu:com.snowplowanalytics.snowplow/timing/jsonschema/1-0-0\",\"data\":{\"category\":\"category\",\"label\":\"label\",\"timing\":10,\"variable\":\"variable\"}}}")
.put("tv", Version.TRACKER)
.put("e", "ue")
.put("ip", "127.0.0.1")
.put("co", EXPECTED_CONTEXTS)
- .put("eid", EXPECTED_EVENT_ID)
.put("tna", "AF003")
.put("tz", "Etc/UTC")
- .put("dtm", "123456")
.put("ttm", "456789")
.put("aid", "cloudfront")
- .build(), result);
+ .build();
+
+ assertTrue(result.entrySet().containsAll(expected.entrySet()));
+
}
// --- Tracker Setter & Getter Tests
@@ -538,17 +551,23 @@ public void testSetDefaultPlatform() {
@Test
public void testSetSubject() {
+ // Subject objects always have timezone set
TimeZone.setDefault(TimeZone.getTimeZone("Etc/UTC"));
+
Subject s1 = new Subject.SubjectBuilder().build();
+ s1.setLanguage("EN");
Tracker tracker = new Tracker.TrackerBuilder(mockEmitter, "AF003", "cloudfront")
.subject(s1)
.build();
+
Subject s2 = new Subject.SubjectBuilder().build();
s2.setColorDepth(24);
tracker.setSubject(s2);
+
Map subjectPairs = new HashMap<>();
subjectPairs.put("tz", "Etc/UTC");
subjectPairs.put("cd", "24");
+
assertEquals(subjectPairs, tracker.getSubject().getSubject());
}
diff --git a/src/test/java/com/snowplowanalytics/snowplow/tracker/emitter/BatchEmitterTest.java b/src/test/java/com/snowplowanalytics/snowplow/tracker/emitter/BatchEmitterTest.java
index 5c310e41..2953c7f1 100644
--- a/src/test/java/com/snowplowanalytics/snowplow/tracker/emitter/BatchEmitterTest.java
+++ b/src/test/java/com/snowplowanalytics/snowplow/tracker/emitter/BatchEmitterTest.java
@@ -25,9 +25,6 @@
import org.junit.Before;
import org.junit.Test;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.*;
-
import com.snowplowanalytics.snowplow.tracker.payload.SelfDescribingJson;
import com.snowplowanalytics.snowplow.tracker.payload.TrackerPayload;
import com.snowplowanalytics.snowplow.tracker.events.PageView;
@@ -60,14 +57,10 @@ public int get(TrackerPayload payload) {
}
@Override
- public String getUrl() {
- return null;
- }
+ public String getUrl() { return null; }
@Override
- public Object getHttpClient() {
- return null;
- }
+ public Object getHttpClient() { return null; }
}
// this class fails to "send" the first 4 requests
@@ -87,19 +80,13 @@ public int post(SelfDescribingJson payload) {
}
@Override
- public int get(TrackerPayload payload) {
- return 0;
- }
+ public int get(TrackerPayload payload) { return 0; }
@Override
- public String getUrl() {
- return null;
- }
+ public String getUrl() { return null; }
@Override
- public Object getHttpClient() {
- return null;
- }
+ public Object getHttpClient() { return null; }
}
@Before
@@ -114,16 +101,15 @@ public void setUp() {
@Test
public void addToBuffer_withLess10Payloads_shouldNotEmptyBuffer() throws InterruptedException {
- List payloads = createPayloads(2);
- for (TrackerPayload payload : payloads) {
- emitter.add(payload);
- }
+ TrackerPayload payload = createPayload();
+ boolean result = emitter.add(payload);
Thread.sleep(500);
+ Assert.assertTrue(result);
Assert.assertFalse(mockHttpClientAdapter.isPostCalled);
- Assert.assertEquals(2, emitter.getBuffer().size());
- Assert.assertEquals(payloads, emitter.getBuffer());
+ Assert.assertEquals(1, emitter.getBuffer().size());
+ Assert.assertEquals(payload, emitter.getBuffer().get(0));
}
@Test
@@ -136,8 +122,6 @@ public void addToBuffer_withMore10Payloads_shouldEmptyBuffer() throws Interrupte
Thread.sleep(500);
Assert.assertTrue(mockHttpClientAdapter.isPostCalled);
- @SuppressWarnings("unchecked")
- List