diff --git a/src/main/groovy/com/mhackner/cloudflare/AsyncCloudFlareClient.groovy b/src/main/groovy/com/mhackner/cloudflare/AsyncCloudFlareClient.groovy index 62c8915..1939009 100644 --- a/src/main/groovy/com/mhackner/cloudflare/AsyncCloudFlareClient.groovy +++ b/src/main/groovy/com/mhackner/cloudflare/AsyncCloudFlareClient.groovy @@ -2,6 +2,7 @@ package com.mhackner.cloudflare import groovyx.net.http.AsyncHTTPBuilder import groovyx.net.http.ContentType +import groovyx.net.http.HTTPBuilder import groovyx.net.http.HttpResponseException import groovyx.net.http.Method @@ -77,6 +78,15 @@ class AsyncCloudFlareClient { } } + Future purgeCache(String zoneId, Collection urls = null, Collection tags = null) { + def body = urls || tags ? [files: urls, tags: tags].findAll { it.value } : [purge_everything: true] + new ResultExtractor(http.doRequest(new HTTPBuilder.RequestConfigDelegate( + http, + [path: "zones/$zoneId/purge_cache", body: body], + new HttpDeleteWithBody(), + null))) + } + private static class ResultExtractor { @Delegate Future delegate diff --git a/src/main/groovy/com/mhackner/cloudflare/CloudFlareClient.groovy b/src/main/groovy/com/mhackner/cloudflare/CloudFlareClient.groovy index 4e6026a..6ec935b 100644 --- a/src/main/groovy/com/mhackner/cloudflare/CloudFlareClient.groovy +++ b/src/main/groovy/com/mhackner/cloudflare/CloudFlareClient.groovy @@ -1,6 +1,7 @@ package com.mhackner.cloudflare import groovyx.net.http.ContentType +import groovyx.net.http.HTTPBuilder import groovyx.net.http.RESTClient class CloudFlareClient { @@ -64,4 +65,13 @@ class CloudFlareClient { http.put(path: "zones/$record.zone_id/dns_records/$record.id", body: record).data.result } + Map purgeCache(String zoneId, Collection urls = null, Collection tags = null) { + def body = urls || tags ? [files: urls, tags: tags].findAll { it.value } : [purge_everything: true] + http.doRequest(new HTTPBuilder.RequestConfigDelegate( + http, + [path: "zones/$zoneId/purge_cache", body: body], + new HttpDeleteWithBody(), + null)).data.result + } + } diff --git a/src/main/groovy/com/mhackner/cloudflare/HttpDeleteWithBody.groovy b/src/main/groovy/com/mhackner/cloudflare/HttpDeleteWithBody.groovy new file mode 100644 index 0000000..c967f35 --- /dev/null +++ b/src/main/groovy/com/mhackner/cloudflare/HttpDeleteWithBody.groovy @@ -0,0 +1,23 @@ +package com.mhackner.cloudflare + +import groovy.transform.PackageScope + +import org.apache.http.annotation.NotThreadSafe +import org.apache.http.client.methods.HttpEntityEnclosingRequestBase + +@NotThreadSafe +@PackageScope +class HttpDeleteWithBody extends HttpEntityEnclosingRequestBase { + + public static final String METHOD_NAME = 'DELETE' + + HttpDeleteWithBody() { + super() + } + + @Override + String getMethod() { + METHOD_NAME + } + +} diff --git a/src/test/groovy/com/mhackner/cloudflare/CloudFlareClientTest.groovy b/src/test/groovy/com/mhackner/cloudflare/CloudFlareClientTest.groovy index 410c933..29b9d24 100644 --- a/src/test/groovy/com/mhackner/cloudflare/CloudFlareClientTest.groovy +++ b/src/test/groovy/com/mhackner/cloudflare/CloudFlareClientTest.groovy @@ -141,4 +141,49 @@ class CloudFlareClientTest { }'''))) } + @Test + void purgeCacheAll() { + client.purgeCache('023e105f4ecef8ad9ca31a8372d0c353') + asyncClient.purgeCache('023e105f4ecef8ad9ca31a8372d0c353').get() + verify(2, deleteRequestedFor(urlEqualTo('/zones/023e105f4ecef8ad9ca31a8372d0c353/purge_cache')) + .withRequestBody(equalToJson(''' + { + "purge_everything": true + }'''))) + } + + @Test + void purgeCacheFiles() { + client.purgeCache('023e105f4ecef8ad9ca31a8372d0c353', ['http://www.example.com/css/styles.css']) + asyncClient.purgeCache('023e105f4ecef8ad9ca31a8372d0c353', ['http://www.example.com/css/styles.css']).get() + verify(2, deleteRequestedFor(urlEqualTo('/zones/023e105f4ecef8ad9ca31a8372d0c353/purge_cache')) + .withRequestBody(equalToJson(''' + { + "files": ["http://www.example.com/css/styles.css"] + }'''))) + } + + @Test + void purgeCacheTags() { + client.purgeCache('023e105f4ecef8ad9ca31a8372d0c353', null, ['tag']) + asyncClient.purgeCache('023e105f4ecef8ad9ca31a8372d0c353', null, ['tag']).get() + verify(2, deleteRequestedFor(urlEqualTo('/zones/023e105f4ecef8ad9ca31a8372d0c353/purge_cache')) + .withRequestBody(equalToJson(''' + { + "tags": ["tag"] + }'''))) + } + + @Test + void purgeCacheBoth() { + client.purgeCache('023e105f4ecef8ad9ca31a8372d0c353', ['http://www.example.com/css/styles.css'], ['tag']) + asyncClient.purgeCache('023e105f4ecef8ad9ca31a8372d0c353', ['http://www.example.com/css/styles.css'], ['tag']).get() + verify(2, deleteRequestedFor(urlEqualTo('/zones/023e105f4ecef8ad9ca31a8372d0c353/purge_cache')) + .withRequestBody(equalToJson(''' + { + "files": ["http://www.example.com/css/styles.css"], + "tags": ["tag"] + }'''))) + } + } diff --git a/src/test/resources/mappings/purgeCacheAll.json b/src/test/resources/mappings/purgeCacheAll.json new file mode 100644 index 0000000..5074373 --- /dev/null +++ b/src/test/resources/mappings/purgeCacheAll.json @@ -0,0 +1,23 @@ +{ + "request": { + "method": "DELETE", + "url": "/zones/023e105f4ecef8ad9ca31a8372d0c353/purge_cache", + "bodyPatterns": [{ + "equalToJson": "{ \"purge_everything\": true }" + }] + }, + "response": { + "status": 200, + "jsonBody": { + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "023e105f4ecef8ad9ca31a8372d0c353" + } + }, + "headers": { + "Content-Type": "application/json" + } + } +} diff --git a/src/test/resources/mappings/purgeCacheBoth.json b/src/test/resources/mappings/purgeCacheBoth.json new file mode 100644 index 0000000..9667e37 --- /dev/null +++ b/src/test/resources/mappings/purgeCacheBoth.json @@ -0,0 +1,23 @@ +{ + "request": { + "method": "DELETE", + "url": "/zones/023e105f4ecef8ad9ca31a8372d0c353/purge_cache", + "bodyPatterns": [{ + "equalToJson": "{ \"files\": [\"http://www.example.com/css/styles.css\"], \"tags\": [\"tag\"] }" + }] + }, + "response": { + "status": 200, + "jsonBody": { + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "023e105f4ecef8ad9ca31a8372d0c353" + } + }, + "headers": { + "Content-Type": "application/json" + } + } +} diff --git a/src/test/resources/mappings/purgeCacheFiles.json b/src/test/resources/mappings/purgeCacheFiles.json new file mode 100644 index 0000000..2648a3a --- /dev/null +++ b/src/test/resources/mappings/purgeCacheFiles.json @@ -0,0 +1,23 @@ +{ + "request": { + "method": "DELETE", + "url": "/zones/023e105f4ecef8ad9ca31a8372d0c353/purge_cache", + "bodyPatterns": [{ + "equalToJson": "{ \"files\": [\"http://www.example.com/css/styles.css\"] }" + }] + }, + "response": { + "status": 200, + "jsonBody": { + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "023e105f4ecef8ad9ca31a8372d0c353" + } + }, + "headers": { + "Content-Type": "application/json" + } + } +} diff --git a/src/test/resources/mappings/purgeCacheTags.json b/src/test/resources/mappings/purgeCacheTags.json new file mode 100644 index 0000000..3b5f328 --- /dev/null +++ b/src/test/resources/mappings/purgeCacheTags.json @@ -0,0 +1,23 @@ +{ + "request": { + "method": "DELETE", + "url": "/zones/023e105f4ecef8ad9ca31a8372d0c353/purge_cache", + "bodyPatterns": [{ + "equalToJson": "{ \"tags\": [\"tag\"] }" + }] + }, + "response": { + "status": 200, + "jsonBody": { + "success": true, + "errors": [], + "messages": [], + "result": { + "id": "023e105f4ecef8ad9ca31a8372d0c353" + } + }, + "headers": { + "Content-Type": "application/json" + } + } +}