use of com.optimizely.ab.event.LogEvent in project java-sdk by optimizely.
the class EventBuilder method createImpressionEvent.
public LogEvent createImpressionEvent(@Nonnull ProjectConfig projectConfig, @Nonnull Experiment activatedExperiment, @Nonnull Variation variation, @Nonnull String userId, @Nonnull Map<String, String> attributes) {
Decision decision = new Decision(activatedExperiment.getLayerId(), activatedExperiment.getId(), variation.getId(), false);
Event impressionEvent = new Event(System.currentTimeMillis(), UUID.randomUUID().toString(), activatedExperiment.getLayerId(), ACTIVATE_EVENT_KEY, null, null, null, ACTIVATE_EVENT_KEY, null);
Snapshot snapshot = new Snapshot(Arrays.asList(decision), Arrays.asList(impressionEvent));
Visitor visitor = new Visitor(userId, null, buildAttributeList(projectConfig, attributes), Arrays.asList(snapshot));
List<Visitor> visitors = Arrays.asList(visitor);
EventBatch eventBatch = new EventBatch(clientEngine.getClientEngineValue(), clientVersion, projectConfig.getAccountId(), visitors, projectConfig.getAnonymizeIP(), projectConfig.getProjectId(), projectConfig.getRevision());
String payload = this.serializer.serialize(eventBatch);
return new LogEvent(LogEvent.RequestMethod.POST, EVENT_ENDPOINT, Collections.<String, String>emptyMap(), payload);
}
use of com.optimizely.ab.event.LogEvent in project java-sdk by optimizely.
the class OptimizelyTest method trackEventEndToEndForced.
// ======== track tests ========//
/**
* Verify that the {@link Optimizely#track(String, String)} call correctly builds a V2 event and passes it
* through {@link EventHandler#dispatchEvent(LogEvent)}.
*/
@Test
public void trackEventEndToEndForced() throws Exception {
EventType eventType;
String datafile;
ProjectConfig config;
if (datafileVersion >= 4) {
config = spy(validProjectConfig);
eventType = validProjectConfig.getEventNameMapping().get(EVENT_BASIC_EVENT_KEY);
datafile = validDatafile;
} else {
config = spy(noAudienceProjectConfig);
eventType = noAudienceProjectConfig.getEventTypes().get(0);
datafile = noAudienceDatafile;
}
List<Experiment> allExperiments = new ArrayList<Experiment>();
allExperiments.add(config.getExperiments().get(0));
EventBuilder eventBuilder = new EventBuilder();
DecisionService spyDecisionService = spy(new DecisionService(mockBucketer, mockErrorHandler, config, null));
Optimizely optimizely = Optimizely.builder(datafile, mockEventHandler).withDecisionService(spyDecisionService).withEventBuilder(eventBuilder).withConfig(noAudienceProjectConfig).withErrorHandler(mockErrorHandler).build();
// call the bucket function.
for (Experiment experiment : allExperiments) {
when(mockBucketer.bucket(experiment, testUserId)).thenReturn(null);
}
// call get forced.
for (Experiment experiment : allExperiments) {
optimizely.projectConfig.setForcedVariation(experiment.getKey(), testUserId, experiment.getVariations().get(0).getKey());
}
// call track
optimizely.track(eventType.getKey(), testUserId);
// verify that the bucketing algorithm was called only on experiments corresponding to the specified goal.
List<Experiment> experimentsForEvent = config.getExperimentsForEventKey(eventType.getKey());
for (Experiment experiment : allExperiments) {
if (experiment.isRunning() && experimentsForEvent.contains(experiment)) {
verify(spyDecisionService).getVariation(experiment, testUserId, Collections.<String, String>emptyMap());
verify(config).getForcedVariation(experiment.getKey(), testUserId);
} else {
verify(spyDecisionService, never()).getVariation(experiment, testUserId, Collections.<String, String>emptyMap());
}
}
// verify that dispatchEvent was called
verify(mockEventHandler).dispatchEvent(any(LogEvent.class));
for (Experiment experiment : allExperiments) {
assertEquals(optimizely.projectConfig.getForcedVariation(experiment.getKey(), testUserId), experiment.getVariations().get(0));
optimizely.projectConfig.setForcedVariation(experiment.getKey(), testUserId, null);
assertNull(optimizely.projectConfig.getForcedVariation(experiment.getKey(), testUserId));
}
}
use of com.optimizely.ab.event.LogEvent in project java-sdk by optimizely.
the class OptimizelyTest method trackEventWithUnknownAttribute.
/**
* Verify that {@link Optimizely#track(String, String)} handles the case where an unknown attribute
* (i.e., not in the config) is passed through.
*
* In this case, the track event call should remove the unknown attribute from the given map.
*/
@Test
@SuppressWarnings("unchecked")
public void trackEventWithUnknownAttribute() throws Exception {
EventType eventType;
if (datafileVersion >= 4) {
eventType = validProjectConfig.getEventNameMapping().get(EVENT_BASIC_EVENT_KEY);
} else {
eventType = validProjectConfig.getEventTypes().get(0);
}
// setup a mock event builder to return expected conversion params
EventBuilder mockEventBuilder = mock(EventBuilder.class);
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler).withBucketing(mockBucketer).withEventBuilder(mockEventBuilder).withConfig(validProjectConfig).withErrorHandler(new RaiseExceptionErrorHandler()).build();
Map<String, String> testParams = new HashMap<String, String>();
testParams.put("test", "params");
Map<Experiment, Variation> experimentVariationMap = createExperimentVariationMap(validProjectConfig, mockDecisionService, eventType.getKey(), genericUserId, Collections.<String, String>emptyMap());
LogEvent logEventToDispatch = new LogEvent(RequestMethod.GET, "test_url", testParams, "");
when(mockEventBuilder.createConversionEvent(eq(validProjectConfig), eq(experimentVariationMap), eq(genericUserId), eq(eventType.getId()), eq(eventType.getKey()), anyMapOf(String.class, String.class), eq(Collections.<String, Object>emptyMap()))).thenReturn(logEventToDispatch);
logbackVerifier.expectMessage(Level.INFO, "Tracking event \"" + eventType.getKey() + "\" for user \"" + genericUserId + "\".");
logbackVerifier.expectMessage(Level.WARN, "Attribute(s) [unknownAttribute] not in the datafile.");
logbackVerifier.expectMessage(Level.DEBUG, "Dispatching conversion event to URL test_url with params " + testParams + " and payload \"\"");
// call track
optimizely.track(eventType.getKey(), genericUserId, ImmutableMap.of("unknownAttribute", "attributeValue"));
// setup the attribute map captor (so we can verify its content)
ArgumentCaptor<Map> attributeCaptor = ArgumentCaptor.forClass(Map.class);
// verify that the event builder was called with the expected attributes
verify(mockEventBuilder).createConversionEvent(eq(validProjectConfig), eq(experimentVariationMap), eq(genericUserId), eq(eventType.getId()), eq(eventType.getKey()), attributeCaptor.capture(), eq(Collections.<String, Object>emptyMap()));
Map<String, String> actualValue = attributeCaptor.getValue();
assertThat(actualValue, not(hasKey("unknownAttribute")));
verify(mockEventHandler).dispatchEvent(logEventToDispatch);
}
use of com.optimizely.ab.event.LogEvent in project java-sdk by optimizely.
the class OptimizelyTest method trackDispatchEventThrowsException.
/**
* Verify that {@link Optimizely#track(String, String)} handles exceptions thrown by
* {@link EventHandler#dispatchEvent(LogEvent)} gracefully.
*/
@Test
public void trackDispatchEventThrowsException() throws Exception {
EventType eventType = noAudienceProjectConfig.getEventTypes().get(0);
doThrow(new Exception("Test Exception")).when(mockEventHandler).dispatchEvent(any(LogEvent.class));
Optimizely optimizely = Optimizely.builder(noAudienceDatafile, mockEventHandler).withConfig(noAudienceProjectConfig).build();
logbackVerifier.expectMessage(Level.ERROR, "Unexpected exception in event dispatcher");
optimizely.track(eventType.getKey(), testUserId);
}
use of com.optimizely.ab.event.LogEvent in project java-sdk by optimizely.
the class Optimizely method track.
public void track(@Nonnull String eventName, @Nonnull String userId, @Nonnull Map<String, String> attributes, @Nonnull Map<String, ?> eventTags) throws UnknownEventTypeException {
ProjectConfig currentConfig = getProjectConfig();
EventType eventType = getEventTypeOrThrow(currentConfig, eventName);
if (eventType == null) {
// if no matching event type could be found, do not dispatch an event
logger.info("Not tracking event \"{}\" for user \"{}\".", eventName, userId);
return;
}
// determine whether all the given attributes are present in the project config. If not, filter out the unknown
// attributes.
Map<String, String> filteredAttributes = filterAttributes(currentConfig, attributes);
if (eventTags == null) {
logger.warn("Event tags is null when non-null was expected. Defaulting to an empty event tags map.");
eventTags = Collections.<String, String>emptyMap();
}
List<Experiment> experimentsForEvent = projectConfig.getExperimentsForEventKey(eventName);
Map<Experiment, Variation> experimentVariationMap = new HashMap<Experiment, Variation>(experimentsForEvent.size());
for (Experiment experiment : experimentsForEvent) {
if (experiment.isRunning()) {
Variation variation = decisionService.getVariation(experiment, userId, filteredAttributes);
if (variation != null) {
experimentVariationMap.put(experiment, variation);
}
} else {
logger.info("Not tracking event \"{}\" for experiment \"{}\" because experiment has status \"Launched\".", eventType.getKey(), experiment.getKey());
}
}
// create the conversion event request parameters, then dispatch
LogEvent conversionEvent = eventBuilder.createConversionEvent(projectConfig, experimentVariationMap, userId, eventType.getId(), eventType.getKey(), filteredAttributes, eventTags);
if (conversionEvent == null) {
logger.info("There are no valid experiments for event \"{}\" to track.", eventName);
logger.info("Not tracking event \"{}\" for user \"{}\".", eventName, userId);
return;
}
logger.info("Tracking event \"{}\" for user \"{}\".", eventName, userId);
logger.debug("Dispatching conversion event to URL {} with params {} and payload \"{}\".", conversionEvent.getEndpointUrl(), conversionEvent.getRequestParams(), conversionEvent.getBody());
try {
eventHandler.dispatchEvent(conversionEvent);
} catch (Exception e) {
logger.error("Unexpected exception in event dispatcher", e);
}
notificationCenter.sendNotifications(NotificationCenter.NotificationType.Track, eventName, userId, filteredAttributes, eventTags, conversionEvent);
}
Aggregations