package com.ge.snowizard.application.resources; import static com.google.common.base.Preconditions.checkNotNull; import io.dropwizard.jersey.caching.CacheControl; import io.dropwizard.jersey.params.IntParam; import io.dropwizard.jersey.protobuf.ProtocolBufferMediaType; import java.util.List; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.glassfish.jersey.server.JSONP; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.codahale.metrics.annotation.Timed; import com.ge.snowizard.api.Id; import com.ge.snowizard.api.protos.SnowizardProtos.SnowizardResponse; import com.ge.snowizard.application.core.MediaTypeAdditional; import com.ge.snowizard.application.exceptions.SnowizardException; import com.ge.snowizard.core.IdWorker; import com.ge.snowizard.exceptions.InvalidSystemClock; import com.ge.snowizard.exceptions.InvalidUserAgentError; import com.google.common.base.Optional; import com.google.common.collect.Lists; @Path("/") public class IdResource { private static final Logger LOGGER = LoggerFactory .getLogger(IdResource.class); private final IdWorker worker; /** * Constructor * * @param worker */ public IdResource(final IdWorker worker) { this.worker = checkNotNull(worker); } /** * Get a new ID and handle any thrown exceptions * * @param agent * User Agent * @return generated ID * @throws SnowizardException */ public long getId(final String agent) { try { return worker.getId(agent); } catch (final InvalidUserAgentError e) { LOGGER.error("Invalid user agent ({})", agent); throw new SnowizardException(Response.Status.BAD_REQUEST, "Invalid User-Agent header", e); } catch (final InvalidSystemClock e) { LOGGER.error("Invalid system clock", e); throw new SnowizardException(Response.Status.INTERNAL_SERVER_ERROR, e.getMessage(), e); } } /** * Get a new ID as plain text * * @param agent * User Agent * @return generated ID */ @GET @Timed @Produces(MediaType.TEXT_PLAIN) @CacheControl(mustRevalidate = true, noCache = true, noStore = true) public String getIdAsString( @HeaderParam(HttpHeaders.USER_AGENT) final String agent) { return String.valueOf(getId(agent)); } /** * Get a new ID as JSON * * @param agent * User Agent * @return generated ID */ @GET @Timed @JSONP(callback = "callback", queryParam = "callback") @Produces({ MediaType.APPLICATION_JSON, MediaTypeAdditional.APPLICATION_JAVASCRIPT }) @CacheControl(mustRevalidate = true, noCache = true, noStore = true) public Id getIdAsJSON( @HeaderParam(HttpHeaders.USER_AGENT) final String agent) { return new Id(getId(agent)); } /** * Get one or more IDs as a Google Protocol Buffer response * * @param agent * User Agent * @param count * Number of IDs to return * @return generated IDs */ @GET @Timed @Produces(ProtocolBufferMediaType.APPLICATION_PROTOBUF) @CacheControl(mustRevalidate = true, noCache = true, noStore = true) public SnowizardResponse getIdAsProtobuf( @HeaderParam(HttpHeaders.USER_AGENT) final String agent, @QueryParam("count") final Optional<IntParam> count) { final List<Long> ids = Lists.newArrayList(); if (count.isPresent()) { for (int i = 0; i < count.get().get(); i++) { ids.add(getId(agent)); } } else { ids.add(getId(agent)); } return SnowizardResponse.newBuilder().addAllId(ids).build(); } }