All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.indeed.proctor.common.Identifiers Maven / Gradle / Ivy

There is a newer version: 1.9.118-1950c8a
Show newest version
package com.indeed.proctor.common;

import com.google.common.collect.ImmutableMap;
import com.indeed.proctor.common.model.TestType;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * Convenience wrapper for Map, used to select an identifier suitable to resolve
 * test groups for the given experiment.
 */
public class Identifiers {
    @Nonnull private final Map identifierMap;
    private final boolean randomEnabled;

    public Identifiers(@Nonnull final Map identifierMap) {
        this(identifierMap, false);
    }

    /**
     * This constructor can construct instances with randomEnabled == true, which only affects test
     * with TestType.RANDOM, and enables the random behavior. For A/B testing, randomized behavior
     * is typically harmful, because the same test units get different treatment every time,
     * preventing analysis of effects. TestType.RANDOM can be used for non-experimentation purposes,
     * such as gradual rollouts of migrations with e.g. 20% of traffic to be diverged to a different
     * server.
     *
     * 

TestType.RANDOM will only work with apps that use this constructor setting randomEnabled * == true. Please refers to {@link Proctor#determineTestGroups(Identifiers, Map, Map, * Collection)} to know how randomEnabled value is used to enable/disable random behavior for * tests with TestType.RANDOM. * * @param identifierMap: A map from TestType to identifier to use (e.g. ctk, accountId). Note * that it must not has an entry for TestType.RANDOM because proctor generates random values * for this type. * @param randomEnabled: A flag whether random behavior for tests with TestType.RANDOM is * enabled or not. Default is false. */ public Identifiers( @Nonnull final Map identifierMap, final boolean randomEnabled) { if (identifierMap.containsKey(TestType.RANDOM)) { throw new IllegalArgumentException( "Cannot specify " + TestType.RANDOM + " in identifierMap"); } this.identifierMap = identifierMap; this.randomEnabled = randomEnabled; } public Identifiers(final TestType type, final String identifier) { this(Collections.singletonMap(type, identifier)); } public static Identifiers of(final TestType type, final String identifier) { return new Identifiers(type, identifier); } public static Identifiers of( final TestType typeA, final String identifierA, final TestType typeB, final String identifierB) { return new Identifiers(ImmutableMap.of(typeA, identifierA, typeB, identifierB)); } public static Identifiers of( final TestType typeA, final String identifierA, final TestType typeB, final String identifierB, final TestType typeC, final String identifierC) { return new Identifiers( ImmutableMap.of(typeA, identifierA, typeB, identifierB, typeC, identifierC)); } /** @return true if random test group assignment was enabled in constructor. */ public boolean isRandomEnabled() { return randomEnabled; } /** @return a set of all the test types whose identifiers are stored in this object. */ public Set getAvailableTestTypes() { return identifierMap.keySet(); } @CheckForNull public String getIdentifier(final TestType testType) { return identifierMap.get(testType); } @CheckForNull public String getUserId() { return getIdentifier(TestType.USER); } @SuppressWarnings("UnusedDeclaration") @CheckForNull public String getPageId() { return getIdentifier(TestType.PAGE); } @CheckForNull public String getCompanyId() { return getIdentifier(TestType.COMPANY); } @CheckForNull public String getEmail() { return getIdentifier(TestType.EMAIL); } @CheckForNull public String getAccountId() { return getIdentifier(TestType.ACCOUNT); } @Override public boolean equals(final Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } final Identifiers that = (Identifiers) o; return randomEnabled == that.randomEnabled && Objects.equals(identifierMap, that.identifierMap); } @Override public int hashCode() { return Objects.hash(identifierMap, randomEnabled); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy