package com.metabroadcast.atlas.glycerin;

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpBackOffIOExceptionHandler;
import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.apache.ApacheHttpTransport;
import com.google.api.client.util.ExponentialBackOff;
import com.google.common.net.HostSpecifier;

class GlycerinHttpClient {

    private static final ExponentialBackOff BACK_OFF = new ExponentialBackOff.Builder()
        .setInitialIntervalMillis(500)
        .build();

    private final Logger log = LoggerFactory.getLogger(getClass());
    
    private final HostSpecifier host;
    private final String apiKey;
    
    private final HttpRequestFactory requestFactory;

    public GlycerinHttpClient(HostSpecifier host, String apiKey) {
        this.host = checkNotNull(host);
        this.apiKey = checkNotNull(apiKey);
        this.requestFactory = new ApacheHttpTransport()
            .createRequestFactory(new HttpRequestInitializer() {
                @Override
                public void initialize(HttpRequest request) {
                    request.setUnsuccessfulResponseHandler(new HttpBackOffUnsuccessfulResponseHandler(BACK_OFF));
                    request.setIOExceptionHandler(new HttpBackOffIOExceptionHandler(BACK_OFF));
                    request.setParser(new JaxbObjectParser(new NitroJaxbContext().getContext()));
                }
            });
    }
    
    public <R, T> GlycerinResponse<T> get(GlycerinQuery<R, T> q) throws IOException {
        HttpRequest getRequest = requestFactory.buildGetRequest(urlFor(q));
        log.debug("{}", getRequest.getUrl());
        return q.toResponse(getRequest.execute().parseAs(q.type()));
    }
    
    private GenericUrl urlFor(GlycerinQuery<?, ?> q) {
        GenericUrl url = new GenericUrl();
        url.setScheme("http");
        url.setHost(host.toString());
        url.set("api_key", apiKey);
        url.setRawPath(q.resourcePath());
        url.putAll(q.queryParameters());
        return url;
    }

}

@@ -595,16 +595,59 @@
 nsport;%0A
+import com.google.api.client.util.BackOff;%0A
 import c
@@ -769,153 +769,8 @@
  %7B%0A%0A
-    private static final ExponentialBackOff BACK_OFF = new ExponentialBackOff.Builder()%0A        .setInitialIntervalMillis(500)%0A        .build();%0A
 %0A   
@@ -1237,24 +1237,211 @@
 ializer() %7B%0A
+                %0A                private final ExponentialBackOff.Builder BACK_OFF = new ExponentialBackOff.Builder()%0A                    .setInitialIntervalMillis(500);%0A                %0A
             
@@ -1614,32 +1614,33 @@
 onseHandler(
-BACK_OFF
+backOff()
 ));%0A        
@@ -1715,24 +1715,25 @@
 Handler(
-BACK_OFF
+backOff()
 ));%0A    
@@ -1839,24 +1839,132 @@
            %7D
+%0A%0A                private BackOff backOff() %7B%0A                    return BACK_OFF.build();%0A                %7D
 %0A           

Create HTTP BackOffs for thread-safety