Skip to content

Commit

Permalink
Refactor experiment and events getters (#179)
Browse files Browse the repository at this point in the history
* remove throws declarations on methods since we never actually throw. Change docs to explain that we send it to the error handler instead
* rename `getExperimentOrThrow` to `getExperimentForKey`
* rename `getEventTypeOrThrow` to `getEventTypeForName`
* move `getExperimentForKey` from Optimizely.java to ProjectConfig.java
* move `getEventTypeForName` from Optimizely.java to ProjectConfig.java.
  • Loading branch information
wangjoshuah authored Apr 12, 2018
1 parent f55a318 commit 15d5f12
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 63 deletions.
66 changes: 3 additions & 63 deletions core-api/src/main/java/com/optimizely/ab/Optimizely.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import com.optimizely.ab.config.parser.DefaultConfigParser;
import com.optimizely.ab.error.ErrorHandler;
import com.optimizely.ab.error.NoOpErrorHandler;
import com.optimizely.ab.error.RaiseExceptionErrorHandler;
import com.optimizely.ab.event.EventHandler;
import com.optimizely.ab.event.LogEvent;
import com.optimizely.ab.event.internal.BuildVersionInfo;
Expand All @@ -42,7 +41,6 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
Expand Down Expand Up @@ -131,7 +129,7 @@ Variation activate(@Nonnull String experimentKey,

ProjectConfig currentConfig = getProjectConfig();

Experiment experiment = getExperimentOrThrow(currentConfig, experimentKey);
Experiment experiment = currentConfig.getExperimentForKey(experimentKey, errorHandler);
if (experiment == null) {
// if we're unable to retrieve the associated experiment, return null
logger.info("Not activating user \"{}\" for experiment \"{}\".", userId, experimentKey);
Expand Down Expand Up @@ -228,7 +226,7 @@ public void track(@Nonnull String eventName,

ProjectConfig currentConfig = getProjectConfig();

EventType eventType = getEventTypeOrThrow(currentConfig, eventName);
EventType eventType = currentConfig.getEventTypeForName(eventName, errorHandler);
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);
Expand Down Expand Up @@ -638,7 +636,7 @@ Variation getVariation(@Nonnull String experimentKey,

ProjectConfig currentConfig = getProjectConfig();

Experiment experiment = getExperimentOrThrow(currentConfig, experimentKey);
Experiment experiment = currentConfig.getExperimentForKey(experimentKey, errorHandler);
if (experiment == null) {
// if we're unable to retrieve the associated experiment, return null
return null;
Expand Down Expand Up @@ -720,64 +718,6 @@ public UserProfileService getUserProfileService() {

//======== Helper methods ========//

/**
* Helper method to retrieve the {@link Experiment} for the given experiment key.
* If {@link RaiseExceptionErrorHandler} is provided, either an experiment is returned, or an exception is thrown.
* If {@link NoOpErrorHandler} is used, either an experiment or {@code null} is returned.
*
* @param projectConfig the current project config
* @param experimentKey the experiment to retrieve from the current project config
* @return the experiment for given experiment key
*
* @throws UnknownExperimentException if there are no experiments in the current project config with the given
* experiment key
*/
private @CheckForNull Experiment getExperimentOrThrow(@Nonnull ProjectConfig projectConfig,
@Nonnull String experimentKey)
throws UnknownExperimentException {

Experiment experiment = projectConfig
.getExperimentKeyMapping()
.get(experimentKey);

// if the given experiment key isn't present in the config, log and potentially throw an exception
if (experiment == null) {
String unknownExperimentError = String.format("Experiment \"%s\" is not in the datafile.", experimentKey);
logger.error(unknownExperimentError);
errorHandler.handleError(new UnknownExperimentException(unknownExperimentError));
}

return experiment;
}

/**
* Helper method to retrieve the {@link EventType} for the given event name.
* If {@link RaiseExceptionErrorHandler} is provided, either an event type is returned, or an exception is thrown.
* If {@link NoOpErrorHandler} is used, either an event type or {@code null} is returned.
*
* @param projectConfig the current project config
* @param eventName the event type to retrieve from the current project config
* @return the event type for the given event name
*
* @throws UnknownEventTypeException if there are no event types in the current project config with the given name
*/
private EventType getEventTypeOrThrow(ProjectConfig projectConfig, String eventName)
throws UnknownEventTypeException {

EventType eventType = projectConfig
.getEventNameMapping()
.get(eventName);

// if the given event name isn't present in the config, log and potentially throw an exception
if (eventType == null) {
String unknownEventTypeError = String.format("Event \"%s\" is not in the datafile.", eventName);
logger.error(unknownEventTypeError);
errorHandler.handleError(new UnknownEventTypeException(unknownEventTypeError));
}

return eventType;
}

/**
* Helper method to verify that the given attributes map contains only keys that are present in the
* {@link ProjectConfig}.
Expand Down
62 changes: 62 additions & 0 deletions core-api/src/main/java/com/optimizely/ab/config/ProjectConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,17 @@
package com.optimizely.ab.config;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.optimizely.ab.UnknownEventTypeException;
import com.optimizely.ab.UnknownExperimentException;
import com.optimizely.ab.config.audience.Audience;
import com.optimizely.ab.config.audience.Condition;
import com.optimizely.ab.error.ErrorHandler;
import com.optimizely.ab.error.NoOpErrorHandler;
import com.optimizely.ab.error.RaiseExceptionErrorHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
Expand Down Expand Up @@ -210,6 +216,62 @@ public ProjectConfig(String accountId,
}
}

/**
* Helper method to retrieve the {@link Experiment} for the given experiment key.
* If {@link RaiseExceptionErrorHandler} is provided, either an experiment is returned,
* or an exception is sent to the error handler
* if there are no experiments in the project config with the given experiment key.
* If {@link NoOpErrorHandler} is used, either an experiment or {@code null} is returned.
*
* @param experimentKey the experiment to retrieve from the current project config
* @param errorHandler the error handler to send exceptions to
* @return the experiment for given experiment key
*/
@CheckForNull
public Experiment getExperimentForKey(@Nonnull String experimentKey,
@Nonnull ErrorHandler errorHandler) {

Experiment experiment =
getExperimentKeyMapping()
.get(experimentKey);

// if the given experiment key isn't present in the config, log an exception to the error handler
if (experiment == null) {
String unknownExperimentError = String.format("Experiment \"%s\" is not in the datafile.", experimentKey);
logger.error(unknownExperimentError);
errorHandler.handleError(new UnknownExperimentException(unknownExperimentError));
}

return experiment;
}

/**
* Helper method to retrieve the {@link EventType} for the given event name.
* If {@link RaiseExceptionErrorHandler} is provided, either an event type is returned,
* or an exception is sent to the error handler if there are no event types in the project config with the given name.
* If {@link NoOpErrorHandler} is used, either an event type or {@code null} is returned.
*
* @param eventName the event type to retrieve from the current project config
* @param errorHandler the error handler to send exceptions to
* @return the event type for the given event name
*/
public @CheckForNull EventType getEventTypeForName(String eventName, ErrorHandler errorHandler) {

EventType eventType =
getEventNameMapping()
.get(eventName);

// if the given event name isn't present in the config, log an exception to the error handler
if (eventType == null) {
String unknownEventTypeError = String.format("Event \"%s\" is not in the datafile.", eventName);
logger.error(unknownEventTypeError);
errorHandler.handleError(new UnknownEventTypeException(unknownEventTypeError));
}

return eventType;
}


public @Nullable Experiment getExperimentForVariationId(String variationId) {
return this.variationIdToExperimentMapping.get(variationId);
}
Expand Down

0 comments on commit 15d5f12

Please sign in to comment.