Return eventId from Tracker.track() (close #304)#310
Return eventId from Tracker.track() (close #304)#310Miranda Wilson (mscwilson) merged 8 commits intorelease/0.12.0from
Conversation
AlexBenny
left a comment
There was a problem hiding this comment.
Great job 👍
Nice cleaning, better testing, removed a test dependency! 🏆
I added few comments, many of them are just considerations and points of view.
| * 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. |
There was a problem hiding this comment.
So pitiful that those legacy eCommerce transaction events force us to do this :(
I'm wondering... what if we return just the eventID of the transaction event without the eventID of all the ecommerce items events?
Essentially those item events are like entities tracked as events due to legacy.
BTW, just an idea, let's keep this as you implemented now.
| payload.add(Parameter.TR_COUNTRY, this.country); | ||
| payload.add(Parameter.TR_CURRENCY, this.currency); | ||
| return putDefaultParams(payload); | ||
| return putTrueTimestamp(payload); |
There was a problem hiding this comment.
This code is quite ugly because the AbstractEvent tries to cover both types of events: SelfDescribing and atomic (primitive) events.
Otherwise we could use super to pass the values of the abstract class and everything would make much more sense. For example, ScreenView is quite ugly because of this.
A correct distinction between SelfDescribing and Primitive would help to write the code in this way.
public TrackerPayload getPayload() {
TrackerPayload payload = super();
payload.add(Parameter.EVENT [...]
and the abstract class would have...
public TrackerPayload getPayload() {
TrackerPayload payload = new TrackerPayload();
if (getTrueTimestamp() != null) {
payload.add(Parameter.TRUE_TIMESTAMP, Long.toString(getTrueTimestamp()));
}
return payload;
}
Anyway, for now we can't do anything like this. It's ok until we don't change the way the events work in the tracker.
| // this throws an exception if it's not a valid UUID string | ||
| UUID.fromString(result.get(0)); |
There was a problem hiding this comment.
I think we can make this explicit in the test.
Probably the result would be the same but raising an exception in the tests could have an unexpected behaviour not just like a failure. I can't find any reference to support this and it could be I remember cases related to another platform/language (ObjC ?!) but JUnit offers some assert methods for this so it can be worth to use them: https://www.baeldung.com/junit-assert-exception
There was a problem hiding this comment.
Raising an exception does just fail the test, but yeah it would be nicer to assert it explicitly
There was a problem hiding this comment.
No need to change this, I misunderstood the test. The comment made me think to an exception testing but actually you are testing it's successful 👍
There was a problem hiding this comment.
I've changed it anyway. You misread it so it could have been clearer :)
| .build(), result1); | ||
| .build(); | ||
|
|
||
| assertTrue(result1.entrySet().containsAll(expected1.entrySet())); |
| Map<String, String> result2 = results.get(1).getMap(); | ||
| assertEquals(ImmutableMap.<String, String>builder() | ||
| .put("dtm", "123456") | ||
| Map<String, String> expected2 = ImmutableMap.<String, String>builder() |
There was a problem hiding this comment.
It seems the expected2 is the same as expected1. Removing dtm and eid there aren't differences.
Probably it's the same case for other tests.
| subjectPairs.put("tz", "Etc/UTC"); | ||
| subjectPairs.put("cd", "24"); | ||
|
|
||
| assertEquals(subjectPairs, tracker.getSubject().getSubject()); |
There was a problem hiding this comment.
tracker.getSubject().getSubject() :D
| import static org.hamcrest.MatcherAssert.assertThat; | ||
| import static org.hamcrest.Matchers.*; |
| public String getUrl() { | ||
| return null; | ||
| } | ||
| public String getUrl() { return null; } |
There was a problem hiding this comment.
Just my opinion. I don't see this a coding style mistake. For me it's not that wrong to have the function on multiple lines even with a single line block.
| long currentTime = System.currentTimeMillis(); | ||
| TrackerPayload payload = new TrackerPayload(); | ||
| long timeDifference = payload.getDeviceCreatedTimestamp() - currentTime; | ||
| assertTrue(timeDifference < 1000); |
There was a problem hiding this comment.
I guess it could be even less than 1000.
Not a big thing btw.
There was a problem hiding this comment.
actually 100 was too low!
For issue #304.
These changes remove two inappropriate fields from Events, remove the Hamcrest dependency, and add a return type to
Tracker.track().Bad stuff
Previously,
eventIdwas an Event field. Users were able to provide their own event ID when building an Event, or one would be generated automatically. The eventId was passed to the payload on TrackerPayload creation, whenEvent.getPayload()was called duringTracker.track()- or before PR #293, during event sending by the Emitter.Snowplow pipelines rely on eventIds being unique; allowing it to be set manually was very risky.
Users were also still able to set
deviceCreatedTimestamp, a legacy option from before the introduction oftrueTimestamp. TrueTimestamp is designed specifically for users to set their own timestamp. Aside from that, setting deviceCreatedTimestamp then means it referred to when the Event was built, which isn't necessarily when it's tracked.New stuff
EventId and deviceCreatedTimestamp are now fields of TrackerPayload, and are generated automatically on TrackerPayload initialisation. DeviceCreatedTimestamp now more accurately describes the time at which
Tracker.track()was called.Previously, users could access an Event's eventId using
Event.getEventId()for use elsewhere in their application. We now return the eventId fromTracker.track(). If the payload was lost because the Emitter buffer was full, null is returned instead.I also removed the Hamcrest test dependency, which was only used in a couple of places.