Skip to content

Return eventId from Tracker.track() (close #304)#310

Merged
Miranda Wilson (mscwilson) merged 8 commits intorelease/0.12.0from
issue/304-remove_dtm_eid_setters
Mar 8, 2022
Merged

Return eventId from Tracker.track() (close #304)#310
Miranda Wilson (mscwilson) merged 8 commits intorelease/0.12.0from
issue/304-remove_dtm_eid_setters

Conversation

@mscwilson
Copy link
Copy Markdown
Contributor

@mscwilson Miranda Wilson (mscwilson) commented Mar 7, 2022

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, eventId was 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, when Event.getPayload() was called during Tracker.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 of trueTimestamp. 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 from Tracker.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.

@snowplowcla Snowplow CLA bot (snowplowcla) added the cla:no [Auto generated] Snowplow Contributor License Agreement has not been signed. label Mar 7, 2022
@mscwilson Miranda Wilson (mscwilson) removed the cla:no [Auto generated] Snowplow Contributor License Agreement has not been signed. label Mar 7, 2022
Copy link
Copy Markdown
Collaborator

@AlexBenny AlexBenny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job 👍

Nice cleaning, better testing, removed a test dependency! 🏆

I added few comments, many of them are just considerations and points of view.

Comment on lines +198 to +204
* 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.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +80 to +81
// this throws an exception if it's not a valid UUID string
UUID.fromString(result.get(0));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Raising an exception does just fail the test, but yeah it would be nicer to assert it explicitly

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 👍

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed it anyway. You misread it so it could have been clearer :)

.build(), result1);
.build();

assertTrue(result1.entrySet().containsAll(expected1.entrySet()));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 👍 👍

Map<String, String> result2 = results.get(1).getMap();
assertEquals(ImmutableMap.<String, String>builder()
.put("dtm", "123456")
Map<String, String> expected2 = ImmutableMap.<String, String>builder()
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/test/java/com/snowplowanalytics/snowplow/tracker/TrackerTest.java Outdated
subjectPairs.put("tz", "Etc/UTC");
subjectPairs.put("cd", "24");

assertEquals(subjectPairs, tracker.getSubject().getSubject());
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tracker.getSubject().getSubject() :D

Comment on lines -28 to -29
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 👍

Comment on lines -63 to +60
public String getUrl() {
return null;
}
public String getUrl() { return null; }
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it could be even less than 1000.
Not a big thing btw.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually 100 was too low!

@mscwilson Miranda Wilson (mscwilson) merged commit 753ff45 into release/0.12.0 Mar 8, 2022
@mscwilson Miranda Wilson (mscwilson) deleted the issue/304-remove_dtm_eid_setters branch March 8, 2022 11:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants