io.rtr.alchemy.client.AlchemyClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of alchemy-client Show documentation
Show all versions of alchemy-client Show documentation
Client for Alchemy Service
package io.rtr.alchemy.client;
import com.codahale.metrics.MetricRegistry;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.google.common.base.Function;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Maps;
import io.rtr.alchemy.client.builder.CreateExperimentRequestBuilder;
import io.rtr.alchemy.client.builder.GetExperimentsRequestBuilder;
import io.rtr.alchemy.client.builder.UpdateAllocationsRequestBuilder;
import io.rtr.alchemy.client.builder.UpdateExperimentRequestBuilder;
import io.rtr.alchemy.client.builder.UpdateTreatmentRequestBuilder;
import io.rtr.alchemy.dto.identities.IdentityDto;
import io.rtr.alchemy.dto.models.AllocationDto;
import io.rtr.alchemy.dto.models.ExperimentDto;
import io.rtr.alchemy.dto.models.TreatmentDto;
import io.rtr.alchemy.dto.models.TreatmentOverrideDto;
import io.rtr.alchemy.dto.requests.GetExperimentsRequest;
import io.rtr.alchemy.dto.requests.TreatmentOverrideRequest;
import io.dropwizard.client.JerseyClientBuilder;
import io.dropwizard.jackson.Jackson;
import io.dropwizard.setup.Environment;
import org.glassfish.hk2.utilities.reflection.ParameterizedTypeImpl;
import javax.annotation.Nullable;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.Invocation;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/** A Dropwizard client for talking to an instance Alchemy service */
public class AlchemyClient {
private static final String CLIENT_NAME = "alchemy-client";
private static final Map EMPTY_PATH_PARAMS = Maps.newHashMap();
private static final ListMultimap EMPTY_QUERY_PARAMS =
ArrayListMultimap.create();
private static final ClassTypeMapper CLASS_TYPE_MAPPER = new ClassTypeMapper();
private final MetricRegistry metricRegistry = new MetricRegistry();
private final JerseyClientBuilder clientBuilder = new JerseyClientBuilder(metricRegistry);
private final Client client;
private final AlchemyClientConfiguration configuration;
private static final String PARAM_EXPERIMENT_NAME = "experimentName";
private static final String PARAM_TREATMENT_NAME = "treatmentName";
private static final String PARAM_OVERRIDE_NAME = "overrideName";
private static final String PARAM_IDENTITY_TYPE_NAME = "identityType";
private static final String ENDPOINT_EXPERIMENTS = "/experiments";
private static final String ENDPOINT_EXPERIMENT = "/experiments/{experimentName}";
private static final String ENDPOINT_ALLOCATIONS = "/experiments/{experimentName}/allocations";
private static final String ENDPOINT_TREATMENTS = "/experiments/{experimentName}/treatments";
private static final String ENDPOINT_TREATMENT =
"/experiments/{experimentName}/treatments/{treatmentName}";
private static final String ENDPOINT_OVERRIDES = "/experiments/{experimentName}/overrides";
private static final String ENDPOINT_OVERRIDE =
"/experiments/{experimentName}/overrides/{overrideName}";
private static final String ENDPOINT_ACTIVE_TREATMENT =
"/active/experiments/{experimentName}/treatment";
private static final String ENDPOINT_ACTIVE_TREATMENTS = "/active/treatments";
private static final String ENDPOINT_METADATA_IDENTITY_TYPES = "/metadata/identityTypes";
private static final String ENDPOINT_METADATA_IDENTITY_TYPE_SCHEMA =
"/metadata/identityTypes/{identityType}/schema";
private static final String ENDPOINT_METADATA_IDENTITY_TYPE_ATTRIBUTES =
"/metadata/identityTypes/{identityType}/attributes";
private final Function>
GET_EXPERIMENTS_REQUEST_BUILDER =
new Function>() {
@Nullable
@Override
public List apply(@Nullable GetExperimentsRequest request) {
if (request == null) {
return null;
}
final ListMultimap queryParams =
ArrayListMultimap.create();
if (request.getFilter() != null) {
queryParams.put("filter", request.getFilter());
}
if (request.getOffset() != null) {
queryParams.put("offset", request.getOffset());
}
if (request.getLimit() != null) {
queryParams.put("limit", request.getLimit());
}
if (request.getSort() != null) {
queryParams.put("sort", request.getSort());
}
final Invocation.Builder builder =
resource(ENDPOINT_EXPERIMENTS, queryParams);
return builder.get(list(ExperimentDto.class));
}
};
/** Constructs a client with the given dropwizard environment */
public AlchemyClient(AlchemyClientConfiguration configuration, Environment environment) {
this.client = clientBuilder.using(environment).using(configuration).build(CLIENT_NAME);
this.configuration = configuration;
configureObjectMapper(configuration, environment.getObjectMapper());
}
/** Constructs a client with the given executor service and object mapper */
public AlchemyClient(
AlchemyClientConfiguration configuration,
ExecutorService executorService,
ObjectMapper objectMapper) {
this.client =
clientBuilder
.using(executorService, objectMapper)
.using(configuration)
.build(CLIENT_NAME);
this.configuration = configuration;
configureObjectMapper(configuration, objectMapper);
}
/** Constructs a client with the given executor service */
public AlchemyClient(
AlchemyClientConfiguration configuration, ExecutorService executorService) {
final ObjectMapper mapper = Jackson.newObjectMapper();
this.client =
clientBuilder
.using(executorService, mapper)
.using(configuration)
.build(CLIENT_NAME);
this.configuration = configuration;
configureObjectMapper(configuration, mapper);
}
/** Constructs a client with reasonable multi-threading defaults */
public AlchemyClient(AlchemyClientConfiguration configuration) {
final ObjectMapper mapper = Jackson.newObjectMapper();
final ExecutorService executorService =
Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
this.client =
clientBuilder
.using(executorService, mapper)
.using(configuration)
.build(CLIENT_NAME);
this.configuration = configuration;
configureObjectMapper(configuration, mapper);
}
private static void configureObjectMapper(
AlchemyClientConfiguration configuration, ObjectMapper mapper) {
mapper.registerSubtypes(
configuration
.getIdentityTypes()
.toArray(new Class>[configuration.getIdentityTypes().size()]));
}
private URI assembleRequestURI(
Map pathParams, ListMultimap queryParams, String path) {
final UriBuilder builder = UriBuilder.fromUri(configuration.getService()).path(path);
for (String queryParam : queryParams.keySet()) {
final List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy