org.slf4j
diff --git a/src/main/java/io/split/fastly/client/FastlyApiClient.java b/src/main/java/io/split/fastly/client/FastlyApiClient.java
index 759183f..597d776 100644
--- a/src/main/java/io/split/fastly/client/FastlyApiClient.java
+++ b/src/main/java/io/split/fastly/client/FastlyApiClient.java
@@ -4,17 +4,19 @@
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
-import com.ning.http.client.AsyncHttpClient;
-import com.ning.http.client.AsyncHttpClientConfig;
-import com.ning.http.client.FluentCaseInsensitiveStringsMap;
-import com.ning.http.client.FluentStringsMap;
-import com.ning.http.client.Response;
+import java.io.IOException;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Future;
+import org.asynchttpclient.AsyncHttpClientConfig;
+import org.asynchttpclient.BoundRequestBuilder;
+import org.asynchttpclient.DefaultAsyncHttpClient;
+import org.asynchttpclient.DefaultAsyncHttpClientConfig;
+import org.asynchttpclient.Response;
import static io.split.fastly.client.FastlyApiClient.Method.POST;
import static io.split.fastly.client.FastlyApiClient.Method.PURGE;
@@ -23,299 +25,301 @@
/**
* Wrapper client for http://docs.fastly.com/api
- *
+ *
* Created by patricioe on 10/12/15.
*/
public class FastlyApiClient {
- /* package private */ static final String FASTLY_URL = "https://api.fastly.com";
- /* package private */ static final Joiner SURROGATE_KEY_JOINER = Joiner.on(" ");
-
- private final Map _commonHeaders;
- private final AsyncHttpClientConfig _config;
- private final AsyncHttpExecutor _asyncHttpExecutor;
- private final String _serviceId;
- private final String _apiKey;
-
- public FastlyApiClient(final String apiKey, final String serviceId) {
- this(apiKey, serviceId, null);
- }
-
- public FastlyApiClient(final String apiKey, final String serviceId, AsyncHttpClientConfig config) {
- this(apiKey, serviceId, config, null);
- }
-
- /* package private */
- @VisibleForTesting
- FastlyApiClient(final String apiKey, final String serviceId, AsyncHttpClientConfig config, AsyncHttpExecutor executor) {
- _commonHeaders = ImmutableMap.of(
- "Fastly-Key", apiKey,
- "Accept", "application/json",
- "User-Agent", "fastly-api-java-v"+ VersionResolver.instance().getVersion());
- _config = config;
- _apiKey = apiKey;
- _serviceId = serviceId;
- _asyncHttpExecutor = (Objects.isNull(executor)) ? new AsyncHttpExecutorImpl() : executor;
- }
+ /* package private */ static final String FASTLY_URL = "https://api.fastly.com";
+ /* package private */ static final Joiner SURROGATE_KEY_JOINER = Joiner.on(" ");
+
+ private final Map _commonHeaders;
+ private final AsyncHttpClientConfig _config;
+ private final AsyncHttpExecutor _asyncHttpExecutor;
+ private final String _serviceId;
+ private final String _apiKey;
+
+ public FastlyApiClient(final String apiKey, final String serviceId) {
+ this(apiKey, serviceId, null);
+ }
+
+ public FastlyApiClient(final String apiKey, final String serviceId, AsyncHttpClientConfig config) {
+ this(apiKey, serviceId, config, null);
+ }
+
+ /* package private */
+ @VisibleForTesting
+ FastlyApiClient(final String apiKey, final String serviceId, AsyncHttpClientConfig config, AsyncHttpExecutor executor) {
+ _commonHeaders = ImmutableMap.of(
+ "Fastly-Key", apiKey,
+ "Accept", "application/json",
+ "User-Agent", "fastly-api-java-v" + VersionResolver.instance().getVersion());
+ _config = config;
+ _apiKey = apiKey;
+ _serviceId = serviceId;
+ _asyncHttpExecutor = (Objects.isNull(executor)) ? new AsyncHttpExecutorImpl() : executor;
+ }
+
+ public Future vclUpload(int version, String vcl, String id, String name) {
+ return vclUpload(version, vcl, id, name, FASTLY_URL);
+ }
+
+ public Future vclUpload(int version, String vcl, String id, String name, String fastlyUrl) {
+ String apiUrl = String.format("%s/service/%s/version/%d/vcl", fastlyUrl, _serviceId, version);
+ return _asyncHttpExecutor.execute(
+ apiUrl,
+ POST,
+ ImmutableMap.builder()
+ .putAll(_commonHeaders)
+ .put("Content-Type", "application/x-www-form-urlencoded")
+ .build(),
+ ImmutableMap.builder().put("content", vcl).put("name", name).put("id", id).build());
+ }
+
+ public List> vclUpdate(int version, Map vcl) {
+ return vclUpdate(version, vcl, FASTLY_URL);
+ }
+
+ public List> vclUpdate(int version, Map vcl, String fastlyUrl) {
+ return vcl.entrySet().stream().map(e -> {
+ String apiUrl = String.format("%s/service/%s/version/$d/vcl/%s", fastlyUrl, _serviceId, version, e.getKey());
+ return _asyncHttpExecutor.execute(
+ apiUrl,
+ PUT,
+ ImmutableMap.builder()
+ .putAll(_commonHeaders)
+ .put("Content-Type", "application/x-www-form-urlencoded")
+ .build(),
+ ImmutableMap.builder().put("content", e.getValue()).put("name", e.getKey()).build());
+
+ }).collect(toList());
+ }
+
+ public Future purgeUrl(final String url) {
+ return purgeUrl(url, Collections.emptyMap());
+ }
+
+ public Future softPurgeUrl(final String url) {
+ return softPurgeUrl(url, Collections.emptyMap());
+ }
+
+ public Future softPurgeUrl(final String url, Map extraHeaders) {
+ return purgeUrl(url, buildHeaderForSoftPurge(extraHeaders));
+ }
+
+ public Future purgeUrl(final String url, Map extraHeaders) {
+ return _asyncHttpExecutor.execute(
+ url,
+ PURGE,
+ ImmutableMap.builder().putAll(_commonHeaders).putAll(extraHeaders).build(),
+ Collections.emptyMap());
+ }
+
+ public Future purgeKey(String key) {
+ return purgeKey(key, Collections.emptyMap());
+ }
+
+ public Future softPurgeKey(String key) {
+ return softPurgeKey(key, Collections.emptyMap());
+ }
+
+ public Future softPurgeKey(String key, Map extraHeaders) {
+ return purgeKey(key, buildHeaderForSoftPurge(extraHeaders));
+ }
+
+ public Future purgeKey(String key, Map extraHeaders) {
+ return purgeKey(key, extraHeaders, FASTLY_URL);
+ }
+
+ public Future purgeKey(String key, Map extraHeaders, String fastlyUrl) {
+ String apiUrl = String.format("%s/service/%s/purge/%s", fastlyUrl, _serviceId, key);
+ return _asyncHttpExecutor.execute(
+ apiUrl,
+ POST,
+ ImmutableMap.builder()
+ .putAll(_commonHeaders)
+ .putAll(extraHeaders)
+ .build(),
+ Collections.emptyMap());
+ }
+
+ public Future purgeKeys(List keys) {
+ return purgeKeys(keys, FASTLY_URL);
+ }
+
+ public Future purgeKeys(List keys, String fastlyUrl) {
+ return purgeKeys(keys, Collections.emptyMap(), fastlyUrl);
+ }
+
+ public Future softPurgeKeys(List keys) {
+ return softPurgeKeys(keys, FASTLY_URL);
+ }
+
+ public Future softPurgeKeys(List keys, String fastlyUrl) {
+ return purgeKeys(keys, buildHeaderForSoftPurge(Collections.emptyMap()), fastlyUrl);
+ }
+
+ public Future purgeKeys(List keys, Map extraHeaders) {
+ return purgeKeys(keys, extraHeaders, FASTLY_URL);
+ }
+
+ public Future purgeKeys(List keys, Map extraHeaders, String fastlyUrl) {
+ Preconditions.checkNotNull(keys, "keys cannot be null!");
+ Preconditions.checkArgument(keys.size() <= 256, "Fastly can't purge batches of more than 256 keys");
+
+ String apiUrl = String.format("%s/service/%s/purge", fastlyUrl, _serviceId);
+ return _asyncHttpExecutor.execute(
+ apiUrl,
+ POST,
+ ImmutableMap.builder()
+ .putAll(_commonHeaders)
+ .putAll(extraHeaders)
+ .put("Surrogate-Key", SURROGATE_KEY_JOINER.join(keys))
+ .build(),
+ Collections.emptyMap());
+ }
+
+ public Future purgeAll() {
+ return purgeAll(FASTLY_URL);
+ }
+
+ public Future purgeAll(String fastlyURL) {
+ String apiUrl = String.format("%s/service/%s/purge_all", fastlyURL, _serviceId);
+ return _asyncHttpExecutor.execute(
+ apiUrl,
+ POST,
+ _commonHeaders,
+ Collections.emptyMap());
+ }
- public Future vclUpload(int version, String vcl, String id, String name) {
- return vclUpload(version, vcl, id, name, FASTLY_URL);
- }
+ private Map buildHeaderForSoftPurge(Map extraHeaders) {
+ return ImmutableMap.builder().put("Fastly-Soft-Purge", "1").putAll(extraHeaders).build();
+ }
- public Future vclUpload(int version, String vcl, String id, String name, String fastlyUrl) {
- String apiUrl = String.format("%s/service/%s/version/%d/vcl", fastlyUrl, _serviceId, version);
- return _asyncHttpExecutor.execute(
- apiUrl,
- POST,
- ImmutableMap. builder()
- .putAll(_commonHeaders)
- .put("Content-Type", "application/x-www-form-urlencoded")
- .build(),
- ImmutableMap. builder().put("content", vcl).put("name", name).put("id", id).build());
- }
+ public void closeConnectionPool() throws IOException {
+ _asyncHttpExecutor.close();
+ }
- public List> vclUpdate(int version, Map vcl) {
- return vclUpdate(version, vcl, FASTLY_URL);
- }
+ /**
+ * Supports PURGE operations.
+ */
+ static class ExtendedAsyncHttpClient extends DefaultAsyncHttpClient {
- public List> vclUpdate(int version, Map vcl, String fastlyUrl) {
- return vcl.entrySet().stream().map( e -> {
- String apiUrl = String.format("%s/service/%s/version/$d/vcl/%s", fastlyUrl, _serviceId, version, e.getKey());
- return _asyncHttpExecutor.execute(
- apiUrl,
- PUT,
- ImmutableMap. builder()
- .putAll(_commonHeaders)
- .put("Content-Type", "application/x-www-form-urlencoded")
- .build(),
- ImmutableMap. builder().put("content", e.getValue()).put("name", e.getKey()).build());
-
- }).collect(toList());
+ public ExtendedAsyncHttpClient(AsyncHttpClientConfig config) {
+ super(config);
}
- public Future purgeUrl(final String url) {
- return purgeUrl(url, Collections.emptyMap());
+ /**
+ * Prepare an HTTP client PURGE request.
+ *
+ * @param url A well formed URL.
+ * @return {@link BoundRequestBuilder}
+ */
+ public BoundRequestBuilder preparePurge(String url) {
+ return requestBuilder("PURGE", url);
}
+ }
- public Future softPurgeUrl(final String url) {
- return softPurgeUrl(url, Collections.emptyMap());
- }
- public Future softPurgeUrl(final String url, Map extraHeaders) {
- return purgeUrl(url, buildHeaderForSoftPurge(extraHeaders));
- }
+ /* package private */
+ @VisibleForTesting
+ interface AsyncHttpExecutor {
- public Future purgeUrl(final String url, Map extraHeaders) {
- return _asyncHttpExecutor.execute(
- url,
- PURGE,
- ImmutableMap.builder().putAll(_commonHeaders).putAll(extraHeaders).build(),
- Collections.emptyMap());
- }
+ Future execute(String apiUrl, Method method, Map headers, Map parameters);
- public Future purgeKey(String key) {
- return purgeKey(key, Collections.emptyMap());
- }
+ public void close() throws IOException;
+ }
- public Future softPurgeKey(String key) {
- return softPurgeKey(key, Collections.emptyMap());
- }
+ /**
+ * Entity Responsible for executing the requesting against the remote endpoint.
+ */
+ private class AsyncHttpExecutorImpl implements AsyncHttpExecutor {
- public Future softPurgeKey(String key, Map extraHeaders) {
- return purgeKey(key, buildHeaderForSoftPurge(extraHeaders));
- }
+ private ExtendedAsyncHttpClient client;
- public Future purgeKey(String key, Map extraHeaders) {
- return purgeKey(key, extraHeaders, FASTLY_URL);
- }
+ private AsyncHttpClientConfig defaultConfig = new DefaultAsyncHttpClientConfig.Builder()
+ .setMaxConnections(50)
+ .setMaxRequestRetry(3)
+ .setMaxConnections(20000)
+ .build();
- public Future purgeKey(String key, Map extraHeaders, String fastlyUrl) {
- String apiUrl = String.format("%s/service/%s/purge/%s", fastlyUrl, _serviceId, key);
- return _asyncHttpExecutor.execute(
- apiUrl,
- POST,
- ImmutableMap. builder()
- .putAll(_commonHeaders)
- .putAll(extraHeaders)
- .build(),
- Collections.emptyMap());
+ public AsyncHttpExecutorImpl() {
+ client = _config != null ? new ExtendedAsyncHttpClient(_config) : new ExtendedAsyncHttpClient(defaultConfig);
}
- public Future purgeKeys(List keys) {
- return purgeKeys(keys, FASTLY_URL);
- }
+ public void close() throws IOException {
- public Future purgeKeys(List keys, String fastlyUrl) {
- return purgeKeys(keys, Collections.emptyMap(), fastlyUrl);
+ client.close();
}
- public Future softPurgeKeys(List keys) {
- return softPurgeKeys(keys, FASTLY_URL);
- }
+ public Future execute(String apiUrl,
+ Method method,
+ Map headers,
+ Map parameters) {
- public Future softPurgeKeys(List keys, String fastlyUrl) {
- return purgeKeys(keys, buildHeaderForSoftPurge(Collections.emptyMap()), fastlyUrl);
- }
+ BoundRequestBuilder request = getRequestForMethod(apiUrl, method);
- public Future purgeKeys(List keys, Map extraHeaders) {
- return purgeKeys(keys, extraHeaders, FASTLY_URL);
- }
+ build(request, headers, parameters);
- public Future purgeKeys(List keys, Map extraHeaders, String fastlyUrl) {
- Preconditions.checkNotNull(keys, "keys cannot be null!");
- Preconditions.checkArgument(keys.size() <= 256, "Fastly can't purge batches of more than 256 keys");
-
- String apiUrl = String.format("%s/service/%s/purge", fastlyUrl, _serviceId);
- return _asyncHttpExecutor.execute(
- apiUrl,
- POST,
- ImmutableMap. builder()
- .putAll(_commonHeaders)
- .putAll(extraHeaders)
- .put("Surrogate-Key", SURROGATE_KEY_JOINER.join(keys))
- .build(),
- Collections.emptyMap());
+ return request.execute();
}
- public Future purgeAll() {
- return purgeAll(FASTLY_URL);
- }
+ private BoundRequestBuilder getRequestForMethod(String apiURL, Method method) {
- public Future purgeAll(String fastlyURL) {
- String apiUrl = String.format("%s/service/%s/purge_all", fastlyURL, _serviceId);
- return _asyncHttpExecutor.execute(
- apiUrl,
- POST,
- _commonHeaders,
- Collections.emptyMap());
- }
+ if (method == Method.PURGE) {
+ return client.preparePurge(apiURL);
+ }
- private Map buildHeaderForSoftPurge(Map extraHeaders) {
- return ImmutableMap. builder().put("Fastly-Soft-Purge", "1").putAll(extraHeaders).build();
- }
+ if (method == Method.POST) {
+ return client.preparePost(apiURL);
+ }
- public void closeConnectionPool() {
- _asyncHttpExecutor.close();
- }
+ if (method == Method.PUT) {
+ return client.preparePut(apiURL);
+ }
- /**
- * Supports PURGE operations.
- */
- static class ExtendedAsyncHttpClient extends AsyncHttpClient {
-
- public ExtendedAsyncHttpClient(AsyncHttpClientConfig config) {
- super(config);
- }
-
- /**
- * Prepare an HTTP client PURGE request.
- *
- * @param url A well formed URL.
- * @return {@link BoundRequestBuilder}
- */
- public BoundRequestBuilder preparePurge(String url) {
- return requestBuilder("PURGE", url);
- }
- }
+ if (method == Method.DELETE) {
+ return client.prepareDelete(apiURL);
+ }
+ if (method == Method.GET) {
+ return client.prepareGet(apiURL);
+ }
- /* package private */
- @VisibleForTesting
- interface AsyncHttpExecutor {
- Future execute( String apiUrl,Method method, Map headers, Map parameters);
- public void close();
+ return null;
}
- /**
- * Entity Responsible for executing the requesting against the remote endpoint.
- */
- private class AsyncHttpExecutorImpl implements AsyncHttpExecutor {
-
- private ExtendedAsyncHttpClient client;
-
- private AsyncHttpClientConfig defaultConfig = new AsyncHttpClientConfig.Builder()
- .setAllowPoolingConnections(true)
- .setMaxConnections(50)
- .setMaxRequestRetry(3)
- .setMaxConnections(20000)
- .build();
-
- public AsyncHttpExecutorImpl() {
- client = _config != null ? new ExtendedAsyncHttpClient(_config) : new ExtendedAsyncHttpClient(defaultConfig);
- }
-
- public void close() {
- client.close();
- }
-
- public Future execute( String apiUrl,
- Method method,
- Map headers,
- Map parameters) {
-
- AsyncHttpClient.BoundRequestBuilder request = getRequestForMethod(apiUrl, method);
-
- build(request, headers, parameters);
+ private void build(BoundRequestBuilder request, Map headers, Map parameters) {
- return request.execute();
- }
+ Map> fluentCaseInsensitiveStringsMap = new HashMap<>();
+ headers.forEach((k, v) -> fluentCaseInsensitiveStringsMap.put(k, Collections.singletonList(v)));
- private AsyncHttpClient.BoundRequestBuilder getRequestForMethod(String apiURL, Method method) {
+ request.setHeaders(fluentCaseInsensitiveStringsMap);
- if (method == Method.PURGE) {
- return client.preparePurge(apiURL);
- }
+ Map> fluentStringsMap = new HashMap<>();
+ parameters.forEach((k, v) -> fluentStringsMap.put(k, Collections.singletonList(v)));
- if (method == Method.POST) {
- return client.preparePost(apiURL);
- }
-
- if (method == Method.PUT) {
- return client.preparePut(apiURL);
- }
-
- if (method == Method.DELETE) {
- return client.prepareDelete(apiURL);
- }
-
- if (method == Method.GET) {
- return client.prepareGet(apiURL);
- }
-
- return null;
- }
-
- private void build(AsyncHttpClient.BoundRequestBuilder request, Map headers, Map parameters) {
-
- FluentCaseInsensitiveStringsMap fluentCaseInsensitiveStringsMap = new FluentCaseInsensitiveStringsMap();
- headers.forEach(fluentCaseInsensitiveStringsMap::add);
-
- request.setHeaders(fluentCaseInsensitiveStringsMap);
-
- FluentStringsMap fluentStringsMap = new FluentStringsMap();
- parameters.forEach(fluentStringsMap::add);
-
- if (request.build().getMethod().equals("GET")) {
- request.setQueryParams(fluentStringsMap);
- } else {
- request.setFormParams(fluentStringsMap);
- }
-
- String host = headers.get("Host");
- if (host != null) {
- request.setVirtualHost(host);
- }
- }
+ if (request.build().getMethod().equals("GET")) {
+ request.setQueryParams(fluentStringsMap);
+ } else {
+ request.setFormParams(fluentStringsMap);
+ }
+ String host = headers.get("Host");
+ if (host != null) {
+ request.setVirtualHost(host);
+ }
}
- enum Method {
- POST,
- PURGE,
- PUT,
- GET,
- DELETE;
- }
+ }
+
+ enum Method {
+ POST,
+ PURGE,
+ PUT,
+ GET,
+ DELETE;
+ }
}
diff --git a/src/test/java/io/split/fastly/client/FastlyApiClientIntegrationTest.java b/src/test/java/io/split/fastly/client/FastlyApiClientIntegrationTest.java
index 17d7107..4b867d1 100644
--- a/src/test/java/io/split/fastly/client/FastlyApiClientIntegrationTest.java
+++ b/src/test/java/io/split/fastly/client/FastlyApiClientIntegrationTest.java
@@ -1,8 +1,8 @@
package io.split.fastly.client;
import com.google.common.collect.Lists;
-import com.ning.http.client.Response;
import io.split.BaseFastlyTest;
+import org.asynchttpclient.Response;
import org.junit.Ignore;
import org.junit.Test;