-
Notifications
You must be signed in to change notification settings - Fork 32
Refactor EventFactory into static methods. #311
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor EventFactory into static methods. #311
Conversation
Pull Request Test Coverage Report for Build 1100
💛 - Coveralls |
@@ -309,22 +301,18 @@ public void track(@Nonnull String eventName, | |||
logger.warn("Event tags is null when non-null was expected. Defaulting to an empty event tags map."); | |||
} | |||
|
|||
// create the conversion event request parameters, then dispatch | |||
LogEvent conversionEvent = eventFactory.createConversionEvent( | |||
UserEvent event = UserEventFactory.createConversionEvent( | |||
projectConfig, | |||
userId, | |||
eventType.getId(), | |||
eventType.getKey(), | |||
copiedAttributes, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might consider moving the copying of attribute into the factory method -- i never understood why it was here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those attributes get passed around to DecisionService and to Notifications. I think a refactor is a good idea, but will do so in a follow-up PR.
public class ClientEngineInfo { | ||
private static final Logger logger = LoggerFactory.getLogger(ClientEngineInfo.class); | ||
|
||
public static final EventBatch.ClientEngine DEFAULT = EventBatch.ClientEngine.JAVA_SDK; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
side-notes:
- it would be nice to move that enum out of
EventBatch
eventually - it would be nice to if we set this automatically -- there are some fairly well-known ways to test whether current runtime is Android. ultimately, this shouldn't be user-defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I think you can do that for android in general, but then Mobile vs TV is a little more tricky and we do that already here. This is a step into making it less clunky and having to pass that info everywhere.
this.eventKey = eventKey; | ||
this.revenue = revenue; | ||
this.value = value; | ||
this.tags = tags; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we default to Collections.emptyMap()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is enforced in the Optimizely#track
call.
|
||
private ConversionEvent(String eventId, String eventKey, Number revenue, Number value, Map<String, ?> tags) { | ||
this.eventId = eventId; | ||
this.eventKey = eventKey; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a case where it is helpful to allow eventId == null && eventKey == null
aside from having an empty constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is enforced in the Optimizely#track
call.
projectConfig, | ||
userId, | ||
eventType.getId(), | ||
eventType.getKey(), | ||
copiedAttributes, | ||
eventTags); | ||
|
||
// create the conversion event request parameters, then dispatch | ||
LogEvent conversionEvent = EventFactory.createLogEvent(Collections.singletonList(event)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like there's a signature included in this PR that would support EventFactory.createLogEvent(event);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ha yeah, I didn't go back and update all these :)
this.clientEngine = clientEngine; | ||
@Deprecated | ||
public Builder withClientEngine(EventBatch.ClientEngine clientEngine) { | ||
logger.info("Explicitly setting the ClientEngine is no longer supported."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we temporarily bridge to the new ClientEngineInfo
class until future release to avoid silent breakage?
also, this should mention what to use instead and, ideally, the version when it was marked as deprecated
this.tags = tags; | ||
return this; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: convenience method for setting single tag would be nice
public Builder withTag(String tag, Object value) {
this.tags = (this.tags != null) ? this.tags : new HashMap<>();
this.tags.put(tag, value);
return this;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would probably just be used in testing, but I'll review.
|
||
import static com.optimizely.ab.internal.AttributesUtil.isValidNumber; | ||
|
||
public class EventFactory { | ||
private static final Logger logger = LoggerFactory.getLogger(EventFactory.class); | ||
static final String EVENT_ENDPOINT = "https://logx.optimizely.com/v1/events"; // Should be part of the datafile | ||
static final String ACTIVATE_EVENT_KEY = "campaign_activated"; | ||
public static final String EVENT_ENDPOINT = "https://logx.optimizely.com/v1/events"; // Should be part of the datafile |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
side-note: I was hoping to make this DEFAULT_EVENT_ENDPOINT
and add a LogEventFactory
that parametrizes this as well as the other constants we are passing to new LogEvent()
constructor. I expect that ability to customize the URL will be helpful/necessary in future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a valid point, but I want to address it when that feature is supported.
public EventFactory(EventBatch.ClientEngine clientEngine, String clientVersion) { | ||
this.clientEngine = clientEngine; | ||
this.clientVersion = clientVersion; | ||
public static LogEvent createLogEvent(List<UserEvent> userEvents) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
worth documenting this functionality, specifically around returning null
.setTags(eventTags) | ||
.setType(eventType.getKey()) | ||
.setValue(EventTagUtils.getNumericValue(eventTags)) | ||
public static Visitor createConversionEvent(UserEvent userEvent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be private
(like createImpressionEvent
above), no?
After SDK CoP and discussion with @loganlinn I'm going to re-work the |
/** | ||
* UserContext stores the user and project context timestamp and global id. | ||
* | ||
* Alt name EventContext? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer EventContext
. Hard for me to associate UUID
and timestamp
with a userId
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can still have UserContext
which holds userId
and attributes
(and perhaps more things in the future) and then user UserContext
in EventContext
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eh, I can split this out into UserContext
and EventContext
|
||
if (logger.isDebugEnabled()) { | ||
logger.debug( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally found this message useful. Any plans to restore this or moving this to AsyncEventHandler?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea i can move it there.
@@ -309,22 +301,18 @@ public void track(@Nonnull String eventName, | |||
logger.warn("Event tags is null when non-null was expected. Defaulting to an empty event tags map."); | |||
} | |||
|
|||
// create the conversion event request parameters, then dispatch | |||
LogEvent conversionEvent = eventFactory.createConversionEvent( | |||
UserEvent event = UserEventFactory.createConversionEvent( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. May be call this userEvent
to be consistent with how you named it above.
this.clientEngine = clientEngine; | ||
@Deprecated | ||
public Builder withClientEngine(EventBatch.ClientEngine clientEngine) { | ||
logger.info("Deprecated. Setting ClientEngine is now set via ClientEngineInfo."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. Sounds incorrect. Perhaps drop the word Setting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated to "Deprecated. In the future, set ClientEngine via ClientEngineInfo#setClientEngine."
public static void setClientEngine(EventBatch.ClientEngine clientEngine) { | ||
if (clientEngine == null) { | ||
logger.warn("ClientEngine cannot be null, defaulting to {}", ClientEngineInfo.clientEngine.getClientEngineValue()); | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is the default set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default is set above. Initial default is JAVA_SDK
, but can get updated at any time to another valid option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good.
/** | ||
* UserContext stores the user and project context timestamp and global id. | ||
* | ||
* Alt name EventContext? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. This comment may be out of date now?
Summary
This change is in preparation for batching event payloads so we first want to extract separate canonical representations of conversions and impressions disjoint from the EventBatch model used for sending to the logging backend.
This change is in preparation for an
EventProcessor
abstraction. #310 is blocked on this change for a cleaner implementation.