From 63dbab8fdecf64558a787b156edf4d65e211f5fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20L=C3=BCdeke?= Date: Wed, 15 May 2013 07:46:37 +0200 Subject: [PATCH 01/11] Encode Requests with UTF-8 to support German Umlauts in requests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit if i send have e.g an Recipient like this: new MandrillRecipient("Andreas Lüdeke", "mail@bla.de") mandrill returns a HTTP Status 500 wit message "you must specify a key value". This happens due to the fact that the ü is not properly encoded within the StringEntity. By Specifying the correct Encoding it works properly --- .../clients/mandrill/request/MandrillRESTRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java index 5ff8f36..4a5d164 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java @@ -42,7 +42,7 @@ private BaseMandrillResponse performPostRequest(BaseMandrillRequest request, Str request.setKey(config.getApiKey()); HttpPost postRequest = new HttpPost(config.getServiceUrl() + serviceMethod); String postData = getPostData(request); - StringEntity input = new StringEntity(postData); + StringEntity input = new StringEntity(postData, "UFT-8"); input.setContentType("application/json"); postRequest.setEntity(input); From b968a8328c32529fcd2335a57c7828e607fd9871 Mon Sep 17 00:00:00 2001 From: Martin Zapata Date: Wed, 22 May 2013 10:19:07 +1000 Subject: [PATCH 02/11] .gitignore --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f0e4507 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.classpath +.project +.settings +/target From c3878656a7c3384964698c076ce9ce68070a95c1 Mon Sep 17 00:00:00 2001 From: Martin Zapata Date: Wed, 22 May 2013 18:08:46 +1000 Subject: [PATCH 03/11] Added new Mandrill response reject_reason --- .../model/response/message/MessageResponse.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/model/response/message/MessageResponse.java b/src/main/java/com/cribbstechnologies/clients/mandrill/model/response/message/MessageResponse.java index 0d237e4..91645ff 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/model/response/message/MessageResponse.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/model/response/message/MessageResponse.java @@ -1,5 +1,7 @@ package com.cribbstechnologies.clients.mandrill.model.response.message; +import org.codehaus.jackson.annotate.JsonProperty; + import com.cribbstechnologies.clients.mandrill.model.response.BaseMandrillResponse; public class MessageResponse extends BaseMandrillResponse { @@ -7,6 +9,7 @@ public class MessageResponse extends BaseMandrillResponse { String email; String status; String _id; + String rejectReason; public String getEmail() { return email; @@ -31,4 +34,13 @@ public String get_id() { public void set_id(String _id) { this._id = _id; } + + public String getRejectReason() { + return this.rejectReason; + } + + @JsonProperty("reject_reason") + public void setRejectReason(String rejectReason) { + this.rejectReason = rejectReason; + } } From 49a3a83ee137b52e371eb293b36e9e2b5f944cd8 Mon Sep 17 00:00:00 2001 From: Martin Zapata Date: Wed, 22 May 2013 18:09:04 +1000 Subject: [PATCH 04/11] Fixed "UTF-8" mispelling --- .../clients/mandrill/request/MandrillRESTRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java index 4a5d164..2cf41a3 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java @@ -42,7 +42,7 @@ private BaseMandrillResponse performPostRequest(BaseMandrillRequest request, Str request.setKey(config.getApiKey()); HttpPost postRequest = new HttpPost(config.getServiceUrl() + serviceMethod); String postData = getPostData(request); - StringEntity input = new StringEntity(postData, "UFT-8"); + StringEntity input = new StringEntity(postData, "UTF-8"); input.setContentType("application/json"); postRequest.setEntity(input); From ceba6b5032023e2a79b1dc4e801e453ce64b2785 Mon Sep 17 00:00:00 2001 From: Brian Cribbs Date: Sun, 16 Jun 2013 16:29:59 -0400 Subject: [PATCH 05/11] added JSONIgnore --- .../mandrill/model/MandrillResponse.java | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/model/MandrillResponse.java b/src/main/java/com/cribbstechnologies/clients/mandrill/model/MandrillResponse.java index 93beb01..6304ca8 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/model/MandrillResponse.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/model/MandrillResponse.java @@ -1,24 +1,27 @@ package com.cribbstechnologies.clients.mandrill.model; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; + +@JsonIgnoreProperties(ignoreUnknown = true) public class MandrillResponse { - private String responseString; - private boolean success; - - public String getJsonResponse() { - return responseString; - } - - public void setResponseString(String jsonResponse) { - this.responseString = jsonResponse; - } - - public boolean isSuccess() { - return success; - } - - public void setSuccess(boolean success) { - this.success = success; - } - + private String responseString; + private boolean success; + + public String getJsonResponse() { + return responseString; + } + + public void setResponseString(String jsonResponse) { + this.responseString = jsonResponse; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + } From 50547d9b7ce76bac6cb8982ff23f3562ccf3405f Mon Sep 17 00:00:00 2001 From: Brian Cribbs Date: Sun, 16 Jun 2013 17:05:37 -0400 Subject: [PATCH 06/11] started changes for version 0.0.2-SNAPSHOT including deprecations --- pom.xml | 2 +- .../clients/mandrill/it/UsersTest.java | 179 +++++++++------- .../mandrill/model/ServiceMethods.java | 123 ++++++++--- .../model/response/users/PingResponse.java | 20 ++ .../mandrill/request/MandrillRESTRequest.java | 202 +++++++++--------- .../request/MandrillUsersRequest.java | 146 ++++++++----- 6 files changed, 401 insertions(+), 271 deletions(-) create mode 100644 src/main/java/com/cribbstechnologies/clients/mandrill/model/response/users/PingResponse.java diff --git a/pom.xml b/pom.xml index 8bf23b5..dd0f892 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.cribbstechnologies.clients mandrillClient - 0.0.1-SNAPSHOT + 0.0.2-SNAPSHOT jar Java Mandrill Wrapper A Java wrapper for Mandrill diff --git a/src/it/java/com/cribbstechnologies/clients/mandrill/it/UsersTest.java b/src/it/java/com/cribbstechnologies/clients/mandrill/it/UsersTest.java index e67e503..4670343 100644 --- a/src/it/java/com/cribbstechnologies/clients/mandrill/it/UsersTest.java +++ b/src/it/java/com/cribbstechnologies/clients/mandrill/it/UsersTest.java @@ -19,6 +19,7 @@ import com.cribbstechnologies.clients.mandrill.model.MandrillRequestWithEmail; import com.cribbstechnologies.clients.mandrill.model.response.BaseMandrillStringResponse; import com.cribbstechnologies.clients.mandrill.model.response.users.DisableResponse; +import com.cribbstechnologies.clients.mandrill.model.response.users.PingResponse; import com.cribbstechnologies.clients.mandrill.model.response.users.UsersInfoResponse; import com.cribbstechnologies.clients.mandrill.model.response.users.UsersSendersResponse; import com.cribbstechnologies.clients.mandrill.model.response.users.VerifyResponse; @@ -28,87 +29,99 @@ public class UsersTest { - private static MandrillRESTRequest request = new MandrillRESTRequest(); - private static MandrillConfiguration config = new MandrillConfiguration(); - private static MandrillUsersRequest usersRequest = new MandrillUsersRequest(); - private static HttpClient client; - private static ObjectMapper mapper = new ObjectMapper(); - private static Properties props = new Properties(); - - @BeforeClass - public static void beforeClass() { - try { - props.load(UsersTest.class.getClassLoader().getResourceAsStream("mandrill.properties")); - } catch (IOException e) { - fail ("properties file not loaded"); - } - config.setApiKey(props.getProperty("apiKey")); - config.setApiVersion("1.0"); - config.setBaseURL("https://mandrillapp.com/api"); - request.setConfig(config); - request.setObjectMapper(mapper); - usersRequest.setRequest(request); - } - - @Before - public void before() { - client = new DefaultHttpClient(); - request.setHttpClient(client); - } - - @Test - public void testPing() { - BaseMandrillRequest baseRequest = new BaseMandrillRequest(); - try { - BaseMandrillStringResponse response = usersRequest.performPing(baseRequest); - assertEquals("\"PONG!\"", response.getResponse()); - } catch (RequestFailedException e) { - fail(e.getMessage()); - } - } - - @Test - public void testGetInfo() { - BaseMandrillRequest baseRequest = new BaseMandrillRequest(); - try { - UsersInfoResponse response = usersRequest.getInfo(baseRequest); - } catch (RequestFailedException e) { - fail(e.getMessage()); - } - } - - @Test - public void testGetSenders() { - BaseMandrillRequest baseRequest = new BaseMandrillRequest(); - try { - UsersSendersResponse response = usersRequest.getSenders(baseRequest); - } catch (RequestFailedException e) { - e.printStackTrace(); - fail(e.getMessage()); - } - } - - @Test - public void testVerifySender() { - MandrillRequestWithEmail emailRequest = new MandrillRequestWithEmail(); - emailRequest.setEmail(props.getProperty("verify.email")); - try { - VerifyResponse response = usersRequest.verifySender(emailRequest); - } catch (RequestFailedException e) { - e.printStackTrace(); - fail(e.getMessage()); - } - } - - @Test - public void testDisableSender() { - MandrillRequestWithDomain domainRequest = new MandrillRequestWithDomain(); - domainRequest.setDomain("google.com"); - try { - DisableResponse response = usersRequest.disableSender(domainRequest); - } catch (RequestFailedException e) { - e.printStackTrace(); - fail(e.getMessage()); - } - } + private static MandrillRESTRequest request = new MandrillRESTRequest(); + private static MandrillConfiguration config = new MandrillConfiguration(); + private static MandrillUsersRequest usersRequest = new MandrillUsersRequest(); + private static HttpClient client; + private static ObjectMapper mapper = new ObjectMapper(); + private static Properties props = new Properties(); + + @BeforeClass + public static void beforeClass() { + try { + props.load(UsersTest.class.getClassLoader().getResourceAsStream("mandrill.properties")); + } catch (IOException e) { + fail("properties file not loaded"); + } + config.setApiKey(props.getProperty("apiKey")); + config.setApiVersion("1.0"); + config.setBaseURL("https://mandrillapp.com/api"); + request.setConfig(config); + request.setObjectMapper(mapper); + usersRequest.setRequest(request); + } + + @Before + public void before() { + client = new DefaultHttpClient(); + request.setHttpClient(client); + } + + @Test + public void testPing() { + BaseMandrillRequest baseRequest = new BaseMandrillRequest(); + try { + BaseMandrillStringResponse response = usersRequest.performPing(baseRequest); + assertEquals("\"PONG!\"", response.getResponse()); + } catch (RequestFailedException e) { + fail(e.getMessage()); + } + } + + @Test + public void testPing2() { + BaseMandrillRequest baseRequest = new BaseMandrillRequest(); + try { + PingResponse pingResponse = usersRequest.performPing2(baseRequest); + assertEquals("PONG!", pingResponse.getPingResponse()); + } catch (RequestFailedException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + + @Test + public void testGetInfo() { + BaseMandrillRequest baseRequest = new BaseMandrillRequest(); + try { + UsersInfoResponse response = usersRequest.getInfo(baseRequest); + } catch (RequestFailedException e) { + fail(e.getMessage()); + } + } + + @Test + public void testGetSenders() { + BaseMandrillRequest baseRequest = new BaseMandrillRequest(); + try { + UsersSendersResponse response = usersRequest.getSenders(baseRequest); + } catch (RequestFailedException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + + @Test + public void testVerifySender() { + MandrillRequestWithEmail emailRequest = new MandrillRequestWithEmail(); + emailRequest.setEmail(props.getProperty("verify.email")); + try { + VerifyResponse response = usersRequest.verifySender(emailRequest); + } catch (RequestFailedException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + + @Test + public void testDisableSender() { + MandrillRequestWithDomain domainRequest = new MandrillRequestWithDomain(); + domainRequest.setDomain("google.com"); + try { + DisableResponse response = usersRequest.disableSender(domainRequest); + } catch (RequestFailedException e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } } diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/model/ServiceMethods.java b/src/main/java/com/cribbstechnologies/clients/mandrill/model/ServiceMethods.java index 72f5d26..292ec94 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/model/ServiceMethods.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/model/ServiceMethods.java @@ -1,37 +1,100 @@ package com.cribbstechnologies.clients.mandrill.model; public class ServiceMethods { - - public class Users { - public static final String PING = "users/ping.json"; - public static final String INFO = "users/info.json"; - public static final String SENDERS = "users/senders.json"; - public static final String DISABLE_SENDER = "users/disable-sender.json"; - public static final String VERIFY_SENDER = "users/verify-sender.json"; - } - - public class Messages { + + public class Users { + + public static final String PING = "users/ping.json"; + public static final String INFO = "users/info.json"; + public static final String SENDERS = "users/senders.json"; + public static final String PING2 = "users/ping2.json"; + @Deprecated + public static final String DISABLE_SENDER = "users/disable-sender.json"; + @Deprecated + public static final String VERIFY_SENDER = "users/verify-sender.json"; + } + + public class Messages { + public static final String SEND = "messages/send.json"; public static final String SEND_TEMPLATE = "messages/send-template.json"; + public static final String SEARCH = "messages/search.json"; + public static final String PARSE = "messages/parse.json"; + public static final String SEND_RAW = "messages/send-raw.json"; + } + + public class Tags { + + public static final String LIST = "tags/list.json"; + public static final String DELETE = "tags/delete.json"; + public static final String INFO = "tags/info.json"; + public static final String TIME_SERIES = "tags/time-series.json"; + public static final String ALL_TIME_SERIES = "tags/all-time-series.json"; + } + + public class Rejects { + + public static final String ADD = "rejects/add.json"; + public static final String LIST = "rejects/list.json"; + public static final String DELETE = "rejects/delete.json"; + } + + public class Whitelists { + + public static final String ADD = "whitelists/add.json"; + public static final String LIST = "whitelists/list.json"; + public static final String DELETE = "whitelists/delete.json"; + } + + public class Senders { + + public static final String LIST = "senders/list.json"; + public static final String DOMAINS = "senders/domain.json"; + public static final String INFO = "senders/info.json"; + public static final String TIME_SERIES = "senders/time-series.json"; + } + + public class Urls { + + public static final String LIST = "urls/list.json"; + public static final String SEARCH = "urls/search.json"; + public static final String TIME_SERIES = "urls/time-series.json"; + } + + public class Templates { + + public static final String ADD = "templates/add.json"; + public static final String INFO = "templates/info.json"; + public static final String UPDATE = "templates/update.json"; + public static final String PUBLISH = "templates/publish.json"; + public static final String DELETE = "templates/delete.json"; + public static final String LIST = "templates/list.json"; + public static final String TIME_SERIES = "templates/time-series.json"; + public static final String RENDER = "templates/render.json"; + } + + public class Webhooks { + + public static final String LIST = "webhooks/list.json"; + public static final String ADD = "webhooks/add.json"; + public static final String INFO = "webhooks/info.json"; + public static final String UPDATE = "webhooks/update.json"; + public static final String DELETE = "webhooks/delete.json"; + } + + public class Inbound { + + public static final String DOMAINS = "inbound/domains.json"; + public static final String ROUTES = "inbound/routes.json"; + public static final String SEND_RAW = "inbound/send-raw.json"; + } + + public class Exports { + + public static final String INFO = "exports/info.json"; + public static final String LIST = "exports/list.json"; + public static final String REJECTS = "exports/rejects.json"; + public static final String WHITELIST = "exports/whitelist.json"; + public static final String ACTIVITY = "exports/activity.json"; } - - public class Tags { - public static final String LIST = "tags/list.json"; - public static final String TIME_SERIES = "tags/time-series.json"; - public static final String ALL_TIME_SERIES = "tags/all-time-series.json"; - } - - public class Urls { - public static final String LIST = "urls/list.json"; - public static final String SEARCH = "urls/search.json"; - public static final String TIME_SERIES = "urls/time-series.json"; - } - - public class Templates { - public static final String ADD = "templates/add.json"; - public static final String INFO = "templates/info.json"; - public static final String UPDATE = "templates/update.json"; - public static final String DELETE = "templates/delete.json"; - public static final String LIST = "templates/list.json"; - } } diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/model/response/users/PingResponse.java b/src/main/java/com/cribbstechnologies/clients/mandrill/model/response/users/PingResponse.java new file mode 100644 index 0000000..1d05427 --- /dev/null +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/model/response/users/PingResponse.java @@ -0,0 +1,20 @@ +package com.cribbstechnologies.clients.mandrill.model.response.users; + +import org.codehaus.jackson.annotate.JsonProperty; + +import com.cribbstechnologies.clients.mandrill.model.response.BaseMandrillResponse; + +public class PingResponse extends BaseMandrillResponse { + + @JsonProperty("PING") + public String pingResponse; + + public String getPingResponse() { + return pingResponse; + } + + public void setPingResponse(String pingResponse) { + this.pingResponse = pingResponse; + } + +} diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java index 2cf41a3..3b8e82d 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java @@ -18,107 +18,113 @@ import com.cribbstechnologies.clients.mandrill.exception.RequestFailedException; import com.cribbstechnologies.clients.mandrill.model.BaseMandrillRequest; +import com.cribbstechnologies.clients.mandrill.model.ServiceMethods; import com.cribbstechnologies.clients.mandrill.model.response.BaseMandrillAnonymousListResponse; import com.cribbstechnologies.clients.mandrill.model.response.BaseMandrillResponse; import com.cribbstechnologies.clients.mandrill.model.response.BaseMandrillStringResponse; import com.cribbstechnologies.clients.mandrill.util.MandrillConfiguration; - + public class MandrillRESTRequest { - - private MandrillConfiguration config; - private HttpClient httpClient; - private ObjectMapper objectMapper; - - public BaseMandrillResponse postRequest(BaseMandrillRequest request, String serviceMethod, Object responseClass) throws RequestFailedException { - return performPostRequest(request, serviceMethod, responseClass, null); - } - - public BaseMandrillResponse postRequest(BaseMandrillRequest request, String serviceMethod, Object responseClass, TypeReference reference) throws RequestFailedException { - return performPostRequest(request, serviceMethod, responseClass, reference); - } - - private BaseMandrillResponse performPostRequest(BaseMandrillRequest request, String serviceMethod, Object responseClass, TypeReference reference) throws RequestFailedException { - try { - request.setKey(config.getApiKey()); - HttpPost postRequest = new HttpPost(config.getServiceUrl() + serviceMethod); - String postData = getPostData(request); - StringEntity input = new StringEntity(postData, "UTF-8"); - input.setContentType("application/json"); - postRequest.setEntity(input); - - HttpResponse response = httpClient.execute(postRequest); - - - BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent()))); - - StringBuffer sb = new StringBuffer(); - String output; - //System.out.println("Output from Server .... \n"); - while ((output = br.readLine()) != null) { - sb.append(output); - //System.out.println(output); - } - - String responseString = sb.toString(); - if (response.getStatusLine().getStatusCode() != 200) { - throw new RequestFailedException("Failed : HTTP error code : " + response.getStatusLine().getStatusCode() + " " + responseString); - } - - //for whatever reason the ping response isn't well-formed - if (responseString.indexOf("PONG!") > -1) { - return new BaseMandrillStringResponse(responseString); - } - - if (reference == null) { - return convertResponseData(responseString, responseClass); - } else { - return convertAnonymousListResponseData(responseString, responseClass, reference); - } - } catch (MalformedURLException mURLE) { - throw new RequestFailedException("Malformed url", mURLE); - } catch (JsonGenerationException jge) { - throw new RequestFailedException("Json Generation Exception", jge); - } catch (JsonMappingException jme) { - throw new RequestFailedException("Json Mapping Exception", jme); - } catch (IOException ioe) { - throw new RequestFailedException("IOException", ioe); - } - } - - /** - * This method will use the Jackson ObjectMapper to generate Mandrill API compatible JSON - * @param request one of @see com.cribbstechnologies.clients.mandrill.model.MandrillMessageRequest, @see com.cribbstechnologies.clients.mandrill.model.MandrillRequestWithEmail, @see com.cribbstechnologies.clients.mandrill.model.MandrillRequestWithQuery, @see com.cribbstechnologies.clients.mandrill.model.MandrillRequestWithTag, @see com.cribbstechnologies.clients.mandrill.model.MandrillRequestWithUrl - * @return a JSON @see java.lang.String - * @throws IOException - * @throws JsonMappingException - * @throws JsonGenerationException - */ - protected String getPostData(BaseMandrillRequest request) throws JsonGenerationException, JsonMappingException, IOException { - return objectMapper.writeValueAsString(request); - } - - protected BaseMandrillResponse convertResponseData(String response, Object responseClass) throws JsonParseException, JsonMappingException, IOException { - return objectMapper.readValue(response, (Class)responseClass); - } - - protected BaseMandrillResponse convertAnonymousListResponseData(String json, Object responseClass, TypeReference reference) throws JsonParseException, JsonMappingException, IOException { - BaseMandrillAnonymousListResponse response = new BaseMandrillAnonymousListResponse(); - List objectList = objectMapper.readValue(json, reference); - response.setList(objectList); - return response; - } - - public void setConfig(MandrillConfiguration config) { - this.config = config; - } - - public void setHttpClient(HttpClient httpClient) { - this.httpClient = httpClient; - } - - public void setObjectMapper(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; - } - - + + private MandrillConfiguration config; + private HttpClient httpClient; + private ObjectMapper objectMapper; + + public BaseMandrillResponse postRequest(BaseMandrillRequest request, String serviceMethod, Object responseClass) throws RequestFailedException { + return performPostRequest(request, serviceMethod, responseClass, null); + } + + public BaseMandrillResponse postRequest(BaseMandrillRequest request, String serviceMethod, Object responseClass, TypeReference reference) throws RequestFailedException { + return performPostRequest(request, serviceMethod, responseClass, reference); + } + + private BaseMandrillResponse performPostRequest(BaseMandrillRequest request, String serviceMethod, Object responseClass, TypeReference reference) throws RequestFailedException { + try { + request.setKey(config.getApiKey()); + HttpPost postRequest = new HttpPost(config.getServiceUrl() + serviceMethod); + String postData = getPostData(request); + StringEntity input = new StringEntity(postData, "UTF-8"); + input.setContentType("application/json"); + postRequest.setEntity(input); + + HttpResponse response = httpClient.execute(postRequest); + + BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent()))); + + StringBuffer sb = new StringBuffer(); + String output; + // System.out.println("Output from Server .... \n"); + while ((output = br.readLine()) != null) { + sb.append(output); + // System.out.println(output); + } + + String responseString = sb.toString(); + if (response.getStatusLine().getStatusCode() != 200) { + throw new RequestFailedException("Failed : HTTP error code : " + response.getStatusLine().getStatusCode() + " " + responseString); + } + + // for whatever reason the ping response isn't well-formed + if (ServiceMethods.Users.PING.equals(serviceMethod) && responseString.indexOf("PONG!") > -1) { + return new BaseMandrillStringResponse(responseString); + } + + if (reference == null) { + return convertResponseData(responseString, responseClass); + } else { + return convertAnonymousListResponseData(responseString, responseClass, reference); + } + } catch (MalformedURLException mURLE) { + throw new RequestFailedException("Malformed url", mURLE); + } catch (JsonGenerationException jge) { + throw new RequestFailedException("Json Generation Exception", jge); + } catch (JsonMappingException jme) { + throw new RequestFailedException("Json Mapping Exception", jme); + } catch (IOException ioe) { + throw new RequestFailedException("IOException", ioe); + } + } + + /** + * This method will use the Jackson ObjectMapper to generate Mandrill API compatible JSON + * + * @param request + * one of @see com.cribbstechnologies.clients.mandrill.model.MandrillMessageRequest, @see + * com.cribbstechnologies.clients.mandrill.model.MandrillRequestWithEmail, @see + * com.cribbstechnologies.clients.mandrill.model.MandrillRequestWithQuery, @see + * com.cribbstechnologies.clients.mandrill.model.MandrillRequestWithTag, @see + * com.cribbstechnologies.clients.mandrill.model.MandrillRequestWithUrl + * @return a JSON @see java.lang.String + * @throws IOException + * @throws JsonMappingException + * @throws JsonGenerationException + */ + protected String getPostData(BaseMandrillRequest request) throws JsonGenerationException, JsonMappingException, IOException { + return objectMapper.writeValueAsString(request); + } + + protected BaseMandrillResponse convertResponseData(String response, Object responseClass) throws JsonParseException, JsonMappingException, IOException { + return objectMapper.readValue(response, (Class) responseClass); + } + + protected BaseMandrillResponse convertAnonymousListResponseData(String json, Object responseClass, TypeReference reference) throws JsonParseException, JsonMappingException, + IOException { + BaseMandrillAnonymousListResponse response = new BaseMandrillAnonymousListResponse(); + List objectList = objectMapper.readValue(json, reference); + response.setList(objectList); + return response; + } + + public void setConfig(MandrillConfiguration config) { + this.config = config; + } + + public void setHttpClient(HttpClient httpClient) { + this.httpClient = httpClient; + } + + public void setObjectMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + } diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUsersRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUsersRequest.java index 977db39..31ba3bb 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUsersRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUsersRequest.java @@ -14,6 +14,7 @@ import com.cribbstechnologies.clients.mandrill.model.response.BaseMandrillStringResponse; import com.cribbstechnologies.clients.mandrill.model.response.users.DisableResponse; import com.cribbstechnologies.clients.mandrill.model.response.users.MandrillSender; +import com.cribbstechnologies.clients.mandrill.model.response.users.PingResponse; import com.cribbstechnologies.clients.mandrill.model.response.users.UsersInfoResponse; import com.cribbstechnologies.clients.mandrill.model.response.users.UsersSendersResponse; import com.cribbstechnologies.clients.mandrill.model.response.users.VerifyResponse; @@ -23,68 +24,95 @@ * This class holds various functions for the Mandrill Users API. * * @author Brian Cribbs, brian@cribbstechnologies.com - * + * */ public class MandrillUsersRequest { - - MandrillRESTRequest request; - TypeReference> usersListReference = new TypeReference>(){}; - /** - * Return the information about the API-connected user - * @param infoRequest a populated @see com.cribbstechnologies.clients.mandrill.model.BaseMandrillRequest - * @throws RequestFailedException - */ - public UsersInfoResponse getInfo(BaseMandrillRequest infoRequest) throws RequestFailedException { - BaseMandrillResponse response = request.postRequest(infoRequest, ServiceMethods.Users.INFO, UsersInfoResponse.class); - return (UsersInfoResponse) response; - } - - /** - * Validate an API key and respond to a ping - * @param pingRequest a populated @see com.cribbstechnologies.clients.mandrill.model.BaseMandrillRequest - * @throws RequestFailedException - */ - public BaseMandrillStringResponse performPing(BaseMandrillRequest pingRequest) throws RequestFailedException { - BaseMandrillStringResponse response = (BaseMandrillStringResponse) request.postRequest(pingRequest, ServiceMethods.Users.PING, null); - return response; - } - - /** - * Return the senders that have tried to use this account, both verified and unverified - * @param sendersRequest a populated @see com.cribbstechnologies.clients.mandrill.model.BaseMandrillRequest - * @throws RequestFailedException - */ - public UsersSendersResponse getSenders(BaseMandrillRequest sendersRequest) throws RequestFailedException { - UsersSendersResponse response = new UsersSendersResponse(); - response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(sendersRequest, ServiceMethods.Users.SENDERS, UsersSendersResponse.class, usersListReference)).getList()); - return response; - } - - /** - * Disable a sender from being able to send - * @param disableRequest a populated @see com.cribbstechnologies.clients.mandrill.model.MandrillRequestWithEmail - * @throws RequestFailedException - */ - public DisableResponse disableSender(MandrillRequestWithDomain disableRequest) throws RequestFailedException { - return (DisableResponse) request.postRequest(disableRequest, ServiceMethods.Users.DISABLE_SENDER, DisableResponse.class); - } - - /** - * Send an email to the given address to verify that it is an accepted sender for your Mandrill account - * @param verifyRequest a populated @see com.cribbstechnologies.clients.mandrill.model.MandrillRequestWithEmail - * @throws RequestFailedException - */ - public VerifyResponse verifySender(MandrillRequestWithEmail verifyRequest) throws RequestFailedException { - return (VerifyResponse)request.postRequest(verifyRequest, ServiceMethods.Users.VERIFY_SENDER, VerifyResponse.class); - } + MandrillRESTRequest request; + + TypeReference> usersListReference = new TypeReference>() { + }; + + /** + * Return the information about the API-connected user + * + * @param infoRequest + * a populated @see com.cribbstechnologies.clients.mandrill.model.BaseMandrillRequest + * @throws RequestFailedException + */ + public UsersInfoResponse getInfo(BaseMandrillRequest infoRequest) throws RequestFailedException { + BaseMandrillResponse response = request.postRequest(infoRequest, ServiceMethods.Users.INFO, UsersInfoResponse.class); + return (UsersInfoResponse) response; + } + + /** + * Validate an API key and respond to a ping + * + * @param pingRequest + * a populated @see com.cribbstechnologies.clients.mandrill.model.BaseMandrillRequest + * @throws RequestFailedException + */ + public BaseMandrillStringResponse performPing(BaseMandrillRequest pingRequest) throws RequestFailedException { + BaseMandrillStringResponse response = (BaseMandrillStringResponse) request.postRequest(pingRequest, ServiceMethods.Users.PING, null); + return response; + } + + /** + * Validate an API key and respond to a ping, this uses actually formatted JSON response + * + * @param pingRequest + * a populated @see com.cribbstechnologies.clients.mandrill.model.BaseMandrillRequest + * @throws RequestFailedException + */ + public PingResponse performPing2(BaseMandrillRequest pingRequest) throws RequestFailedException { + PingResponse response = (PingResponse) request.postRequest(pingRequest, ServiceMethods.Users.PING2, PingResponse.class); + return response; + } + + /** + * Return the senders that have tried to use this account, both verified and unverified + * + * @param sendersRequest + * a populated @see com.cribbstechnologies.clients.mandrill.model.BaseMandrillRequest + * @throws RequestFailedException + */ + public UsersSendersResponse getSenders(BaseMandrillRequest sendersRequest) throws RequestFailedException { + UsersSendersResponse response = new UsersSendersResponse(); + response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(sendersRequest, ServiceMethods.Users.SENDERS, UsersSendersResponse.class, + usersListReference)).getList()); + return response; + } + + /** + * Disable a sender from being able to send + * + * @param disableRequest + * a populated @see com.cribbstechnologies.clients.mandrill.model.MandrillRequestWithEmail + * @throws RequestFailedException + */ + @Deprecated + public DisableResponse disableSender(MandrillRequestWithDomain disableRequest) throws RequestFailedException { + return (DisableResponse) request.postRequest(disableRequest, ServiceMethods.Users.DISABLE_SENDER, DisableResponse.class); + } + + /** + * Send an email to the given address to verify that it is an accepted sender for your Mandrill account + * + * @param verifyRequest + * a populated @see com.cribbstechnologies.clients.mandrill.model.MandrillRequestWithEmail + * @throws RequestFailedException + */ + @Deprecated + public VerifyResponse verifySender(MandrillRequestWithEmail verifyRequest) throws RequestFailedException { + return (VerifyResponse) request.postRequest(verifyRequest, ServiceMethods.Users.VERIFY_SENDER, VerifyResponse.class); + } + + public void setRequest(MandrillRESTRequest request) { + this.request = request; + } - public void setRequest(MandrillRESTRequest request) { - this.request = request; - } + public TypeReference> getUsersListReference() { + return usersListReference; + } - public TypeReference> getUsersListReference() { - return usersListReference; - } - } From 42f39d896cfb620206632ca5e63e7a87b21c3653 Mon Sep 17 00:00:00 2001 From: Brian Cribbs Date: Sun, 16 Jun 2013 17:13:56 -0400 Subject: [PATCH 07/11] updated request classes to set key based on configuration rather than forcing the user to set it --- .../request/MandrillMessagesRequest.java | 60 ++++++++++------- .../mandrill/request/MandrillRESTRequest.java | 4 ++ .../mandrill/request/MandrillTagsRequest.java | 62 +++++++++-------- .../request/MandrillTemplatesRequest.java | 67 ++++++++++--------- .../mandrill/request/MandrillUrlsRequest.java | 59 +++++++++------- .../request/MandrillUsersRequest.java | 4 ++ 6 files changed, 147 insertions(+), 109 deletions(-) diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillMessagesRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillMessagesRequest.java index f0b7d3d..45e6f76 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillMessagesRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillMessagesRequest.java @@ -14,33 +14,41 @@ /** * This class holds various functions for the Mandrill Messages API + * * @author Brian Cribbs - * + * */ public class MandrillMessagesRequest { - - MandrillRESTRequest request; - TypeReference> messageResponseListReference = new TypeReference>(){}; - - /** - * Send a new transactional message through Mandrill - * @param messageRequest a populated @see com.cribstechnologies.clients.mandrill.model.MandrillMessageRequest - * @throws RequestFailedException - */ - public SendMessageResponse sendMessage(MandrillMessageRequest messageRequest) throws RequestFailedException { - SendMessageResponse response = new SendMessageResponse(); - response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(messageRequest, ServiceMethods.Messages.SEND, SendMessageResponse.class, messageResponseListReference)).getList()); - return response; - } - - public SendMessageResponse sendTemplatedMessage(MandrillTemplatedMessageRequest templateMessage) throws RequestFailedException { - SendMessageResponse response = new SendMessageResponse(); - response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(templateMessage, ServiceMethods.Messages.SEND_TEMPLATE, SendMessageResponse.class, messageResponseListReference)).getList()); - return response; - } - - public void setRequest(MandrillRESTRequest request) { - this.request = request; - } - + + MandrillRESTRequest request; + TypeReference> messageResponseListReference = new TypeReference>() { + }; + + /** + * Send a new transactional message through Mandrill + * + * @param messageRequest + * a populated @see com.cribstechnologies.clients.mandrill.model.MandrillMessageRequest + * @throws RequestFailedException + */ + public SendMessageResponse sendMessage(MandrillMessageRequest messageRequest) throws RequestFailedException { + messageRequest.setKey(request.getConfig().getApiKey()); + SendMessageResponse response = new SendMessageResponse(); + response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(messageRequest, ServiceMethods.Messages.SEND, SendMessageResponse.class, + messageResponseListReference)).getList()); + return response; + } + + public SendMessageResponse sendTemplatedMessage(MandrillTemplatedMessageRequest templateMessage) throws RequestFailedException { + templateMessage.setKey(request.getConfig().getApiKey()); + SendMessageResponse response = new SendMessageResponse(); + response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(templateMessage, ServiceMethods.Messages.SEND_TEMPLATE, + SendMessageResponse.class, messageResponseListReference)).getList()); + return response; + } + + public void setRequest(MandrillRESTRequest request) { + this.request = request; + } + } diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java index 3b8e82d..2f8dacf 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java @@ -127,4 +127,8 @@ public void setObjectMapper(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } + public MandrillConfiguration getConfig() { + return config; + } + } diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTagsRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTagsRequest.java index 0b3bd80..75ef85c 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTagsRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTagsRequest.java @@ -15,31 +15,39 @@ import com.cribbstechnologies.clients.mandrill.model.response.tags.TagWithTime; public class MandrillTagsRequest { - - MandrillRESTRequest request; - - TypeReference> timeTagReference = new TypeReference>(){}; - TypeReference> nameTagReference = new TypeReference>(){}; - - public TagListResponse getList(BaseMandrillRequest tagsRequest) throws RequestFailedException { - TagListResponse response = new TagListResponse(); - response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(tagsRequest, ServiceMethods.Tags.LIST, TagListResponse.class, nameTagReference)).getList()); - return response; - } - - public TagSeriesResponse getTimeSeries(MandrillRequestWithTag tagsRequest) throws RequestFailedException { - TagSeriesResponse response = new TagSeriesResponse(); - response.setList(((BaseMandrillAnonymousListResponse)request.postRequest(tagsRequest, ServiceMethods.Tags.TIME_SERIES, TagSeriesResponse.class, timeTagReference)).getList()); - return response; - } - - public TagSeriesResponse getAllTimeSeries(BaseMandrillRequest tagsRequest) throws RequestFailedException { - TagSeriesResponse response = new TagSeriesResponse(); - response.setList(((BaseMandrillAnonymousListResponse)request.postRequest(tagsRequest, ServiceMethods.Tags.ALL_TIME_SERIES, TagSeriesResponse.class, timeTagReference)).getList()); - return response; - } - - public void setRequest(MandrillRESTRequest request) { - this.request = request; - } + + MandrillRESTRequest request; + + TypeReference> timeTagReference = new TypeReference>() { + }; + TypeReference> nameTagReference = new TypeReference>() { + }; + + public TagListResponse getList(BaseMandrillRequest tagsRequest) throws RequestFailedException { + tagsRequest.setKey(request.getConfig().getApiKey()); + TagListResponse response = new TagListResponse(); + response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(tagsRequest, ServiceMethods.Tags.LIST, TagListResponse.class, nameTagReference)) + .getList()); + return response; + } + + public TagSeriesResponse getTimeSeries(MandrillRequestWithTag tagsRequest) throws RequestFailedException { + tagsRequest.setKey(request.getConfig().getApiKey()); + TagSeriesResponse response = new TagSeriesResponse(); + response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(tagsRequest, ServiceMethods.Tags.TIME_SERIES, TagSeriesResponse.class, + timeTagReference)).getList()); + return response; + } + + public TagSeriesResponse getAllTimeSeries(BaseMandrillRequest tagsRequest) throws RequestFailedException { + tagsRequest.setKey(request.getConfig().getApiKey()); + TagSeriesResponse response = new TagSeriesResponse(); + response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(tagsRequest, ServiceMethods.Tags.ALL_TIME_SERIES, TagSeriesResponse.class, + timeTagReference)).getList()); + return response; + } + + public void setRequest(MandrillRESTRequest request) { + this.request = request; + } } diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTemplatesRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTemplatesRequest.java index 013171d..ba14f92 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTemplatesRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTemplatesRequest.java @@ -14,35 +14,42 @@ import com.cribbstechnologies.clients.mandrill.model.response.templates.TemplateResponse; public class MandrillTemplatesRequest { - - MandrillRESTRequest request; - - TypeReference> templatesListReference = new TypeReference>(){}; - - public TemplateResponse addTemplate(MandrillRequestWithCode addRequest) throws RequestFailedException { - return (TemplateResponse) request.postRequest(addRequest, ServiceMethods.Templates.ADD, TemplateResponse.class); - } - - public TemplateResponse getTemplateInfo(MandrillRequestWithName infoRequest) throws RequestFailedException { - return (TemplateResponse) request.postRequest(infoRequest, ServiceMethods.Templates.INFO, TemplateResponse.class); - } - - public TemplateResponse updateTemplate(MandrillRequestWithCode updateRequest) throws RequestFailedException { - return (TemplateResponse) request.postRequest(updateRequest, ServiceMethods.Templates.UPDATE, TemplateResponse.class); - } - - public TemplateResponse deleteTemplate(MandrillRequestWithName deleteRequest) throws RequestFailedException { - return (TemplateResponse) request.postRequest(deleteRequest, ServiceMethods.Templates.DELETE, TemplateResponse.class); - } - - public TemplateListResponse getTemplates(BaseMandrillRequest listRequest) throws RequestFailedException { - TemplateListResponse response = new TemplateListResponse(); - response.setList(((BaseMandrillAnonymousListResponse)request.postRequest(listRequest, ServiceMethods.Templates.LIST, TemplateResponse.class, templatesListReference)).getList()); - return response; - } - - public void setRequest(MandrillRESTRequest request) { - this.request = request; - } + + MandrillRESTRequest request; + + TypeReference> templatesListReference = new TypeReference>() { + }; + + public TemplateResponse addTemplate(MandrillRequestWithCode addRequest) throws RequestFailedException { + addRequest.setKey(request.getConfig().getApiKey()); + return (TemplateResponse) request.postRequest(addRequest, ServiceMethods.Templates.ADD, TemplateResponse.class); + } + + public TemplateResponse getTemplateInfo(MandrillRequestWithName infoRequest) throws RequestFailedException { + infoRequest.setKey(request.getConfig().getApiKey()); + return (TemplateResponse) request.postRequest(infoRequest, ServiceMethods.Templates.INFO, TemplateResponse.class); + } + + public TemplateResponse updateTemplate(MandrillRequestWithCode updateRequest) throws RequestFailedException { + updateRequest.setKey(request.getConfig().getApiKey()); + return (TemplateResponse) request.postRequest(updateRequest, ServiceMethods.Templates.UPDATE, TemplateResponse.class); + } + + public TemplateResponse deleteTemplate(MandrillRequestWithName deleteRequest) throws RequestFailedException { + deleteRequest.setKey(request.getConfig().getApiKey()); + return (TemplateResponse) request.postRequest(deleteRequest, ServiceMethods.Templates.DELETE, TemplateResponse.class); + } + + public TemplateListResponse getTemplates(BaseMandrillRequest listRequest) throws RequestFailedException { + listRequest.setKey(request.getConfig().getApiKey()); + TemplateListResponse response = new TemplateListResponse(); + response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(listRequest, ServiceMethods.Templates.LIST, TemplateResponse.class, + templatesListReference)).getList()); + return response; + } + + public void setRequest(MandrillRESTRequest request) { + this.request = request; + } } diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUrlsRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUrlsRequest.java index f218de3..c2f8d69 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUrlsRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUrlsRequest.java @@ -15,30 +15,37 @@ public class MandrillUrlsRequest { - MandrillRESTRequest request; - - TypeReference> urlsListReference = new TypeReference>(){}; - - public UrlListResponse getList(BaseMandrillRequest listRequest) throws RequestFailedException { - UrlListResponse response = new UrlListResponse(); - response.setList(((BaseMandrillAnonymousListResponse)request.postRequest(listRequest, ServiceMethods.Urls.LIST, UrlListResponse.class, urlsListReference)).getList()); - return response; - } - - public UrlListResponse doSearch(MandrillRequestWithQuery searchRequest) throws RequestFailedException { - UrlListResponse response = new UrlListResponse(); - response.setList(((BaseMandrillAnonymousListResponse)request.postRequest(searchRequest, ServiceMethods.Urls.SEARCH, UrlListResponse.class, urlsListReference)).getList()); - return response; - } - - public UrlListResponse getTimeSeries(MandrillRequestWithUrl seriesRequest) throws RequestFailedException { - UrlListResponse response = new UrlListResponse(); - response.setList(((BaseMandrillAnonymousListResponse)request.postRequest(seriesRequest, ServiceMethods.Urls.TIME_SERIES, UrlListResponse.class, urlsListReference)).getList()); - return response; - } - - public void setRequest(MandrillRESTRequest request) { - this.request = request; - } - + MandrillRESTRequest request; + + TypeReference> urlsListReference = new TypeReference>() { + }; + + public UrlListResponse getList(BaseMandrillRequest listRequest) throws RequestFailedException { + UrlListResponse response = new UrlListResponse(); + listRequest.setKey(request.getConfig().getApiKey()); + response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(listRequest, ServiceMethods.Urls.LIST, UrlListResponse.class, urlsListReference)) + .getList()); + return response; + } + + public UrlListResponse doSearch(MandrillRequestWithQuery searchRequest) throws RequestFailedException { + UrlListResponse response = new UrlListResponse(); + searchRequest.setKey(request.getConfig().getApiKey()); + response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(searchRequest, ServiceMethods.Urls.SEARCH, UrlListResponse.class, urlsListReference)) + .getList()); + return response; + } + + public UrlListResponse getTimeSeries(MandrillRequestWithUrl seriesRequest) throws RequestFailedException { + seriesRequest.setKey(request.getConfig().getApiKey()); + UrlListResponse response = new UrlListResponse(); + response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(seriesRequest, ServiceMethods.Urls.TIME_SERIES, UrlListResponse.class, + urlsListReference)).getList()); + return response; + } + + public void setRequest(MandrillRESTRequest request) { + this.request = request; + } + } diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUsersRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUsersRequest.java index 31ba3bb..0d7d359 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUsersRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUsersRequest.java @@ -41,6 +41,7 @@ public class MandrillUsersRequest { * @throws RequestFailedException */ public UsersInfoResponse getInfo(BaseMandrillRequest infoRequest) throws RequestFailedException { + infoRequest.setKey(request.getConfig().getApiKey()); BaseMandrillResponse response = request.postRequest(infoRequest, ServiceMethods.Users.INFO, UsersInfoResponse.class); return (UsersInfoResponse) response; } @@ -53,6 +54,7 @@ public UsersInfoResponse getInfo(BaseMandrillRequest infoRequest) throws Request * @throws RequestFailedException */ public BaseMandrillStringResponse performPing(BaseMandrillRequest pingRequest) throws RequestFailedException { + pingRequest.setKey(request.getConfig().getApiKey()); BaseMandrillStringResponse response = (BaseMandrillStringResponse) request.postRequest(pingRequest, ServiceMethods.Users.PING, null); return response; } @@ -65,6 +67,7 @@ public BaseMandrillStringResponse performPing(BaseMandrillRequest pingRequest) t * @throws RequestFailedException */ public PingResponse performPing2(BaseMandrillRequest pingRequest) throws RequestFailedException { + pingRequest.setKey(request.getConfig().getApiKey()); PingResponse response = (PingResponse) request.postRequest(pingRequest, ServiceMethods.Users.PING2, PingResponse.class); return response; } @@ -77,6 +80,7 @@ public PingResponse performPing2(BaseMandrillRequest pingRequest) throws Request * @throws RequestFailedException */ public UsersSendersResponse getSenders(BaseMandrillRequest sendersRequest) throws RequestFailedException { + sendersRequest.setKey(request.getConfig().getApiKey()); UsersSendersResponse response = new UsersSendersResponse(); response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(sendersRequest, ServiceMethods.Users.SENDERS, UsersSendersResponse.class, usersListReference)).getList()); From 00cede7f9404b90c338ab5c342f24fefc853363c Mon Sep 17 00:00:00 2001 From: Brian Cribbs Date: Sun, 16 Jun 2013 17:17:26 -0400 Subject: [PATCH 08/11] just kidding, someone did this more intelligently already --- .../clients/mandrill/request/MandrillMessagesRequest.java | 2 -- .../clients/mandrill/request/MandrillRESTRequest.java | 4 ---- .../clients/mandrill/request/MandrillTagsRequest.java | 3 --- .../clients/mandrill/request/MandrillTemplatesRequest.java | 5 ----- .../clients/mandrill/request/MandrillUrlsRequest.java | 3 --- .../clients/mandrill/request/MandrillUsersRequest.java | 6 +----- 6 files changed, 1 insertion(+), 22 deletions(-) diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillMessagesRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillMessagesRequest.java index 45e6f76..98fdd6c 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillMessagesRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillMessagesRequest.java @@ -32,7 +32,6 @@ public class MandrillMessagesRequest { * @throws RequestFailedException */ public SendMessageResponse sendMessage(MandrillMessageRequest messageRequest) throws RequestFailedException { - messageRequest.setKey(request.getConfig().getApiKey()); SendMessageResponse response = new SendMessageResponse(); response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(messageRequest, ServiceMethods.Messages.SEND, SendMessageResponse.class, messageResponseListReference)).getList()); @@ -40,7 +39,6 @@ public SendMessageResponse sendMessage(MandrillMessageRequest messageRequest) th } public SendMessageResponse sendTemplatedMessage(MandrillTemplatedMessageRequest templateMessage) throws RequestFailedException { - templateMessage.setKey(request.getConfig().getApiKey()); SendMessageResponse response = new SendMessageResponse(); response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(templateMessage, ServiceMethods.Messages.SEND_TEMPLATE, SendMessageResponse.class, messageResponseListReference)).getList()); diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java index 2f8dacf..3b8e82d 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequest.java @@ -127,8 +127,4 @@ public void setObjectMapper(ObjectMapper objectMapper) { this.objectMapper = objectMapper; } - public MandrillConfiguration getConfig() { - return config; - } - } diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTagsRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTagsRequest.java index 75ef85c..0a5d51f 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTagsRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTagsRequest.java @@ -24,7 +24,6 @@ public class MandrillTagsRequest { }; public TagListResponse getList(BaseMandrillRequest tagsRequest) throws RequestFailedException { - tagsRequest.setKey(request.getConfig().getApiKey()); TagListResponse response = new TagListResponse(); response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(tagsRequest, ServiceMethods.Tags.LIST, TagListResponse.class, nameTagReference)) .getList()); @@ -32,7 +31,6 @@ public TagListResponse getList(BaseMandrillRequest tagsRequest) throws RequestFa } public TagSeriesResponse getTimeSeries(MandrillRequestWithTag tagsRequest) throws RequestFailedException { - tagsRequest.setKey(request.getConfig().getApiKey()); TagSeriesResponse response = new TagSeriesResponse(); response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(tagsRequest, ServiceMethods.Tags.TIME_SERIES, TagSeriesResponse.class, timeTagReference)).getList()); @@ -40,7 +38,6 @@ public TagSeriesResponse getTimeSeries(MandrillRequestWithTag tagsRequest) throw } public TagSeriesResponse getAllTimeSeries(BaseMandrillRequest tagsRequest) throws RequestFailedException { - tagsRequest.setKey(request.getConfig().getApiKey()); TagSeriesResponse response = new TagSeriesResponse(); response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(tagsRequest, ServiceMethods.Tags.ALL_TIME_SERIES, TagSeriesResponse.class, timeTagReference)).getList()); diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTemplatesRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTemplatesRequest.java index ba14f92..3a8bdcb 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTemplatesRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillTemplatesRequest.java @@ -21,27 +21,22 @@ public class MandrillTemplatesRequest { }; public TemplateResponse addTemplate(MandrillRequestWithCode addRequest) throws RequestFailedException { - addRequest.setKey(request.getConfig().getApiKey()); return (TemplateResponse) request.postRequest(addRequest, ServiceMethods.Templates.ADD, TemplateResponse.class); } public TemplateResponse getTemplateInfo(MandrillRequestWithName infoRequest) throws RequestFailedException { - infoRequest.setKey(request.getConfig().getApiKey()); return (TemplateResponse) request.postRequest(infoRequest, ServiceMethods.Templates.INFO, TemplateResponse.class); } public TemplateResponse updateTemplate(MandrillRequestWithCode updateRequest) throws RequestFailedException { - updateRequest.setKey(request.getConfig().getApiKey()); return (TemplateResponse) request.postRequest(updateRequest, ServiceMethods.Templates.UPDATE, TemplateResponse.class); } public TemplateResponse deleteTemplate(MandrillRequestWithName deleteRequest) throws RequestFailedException { - deleteRequest.setKey(request.getConfig().getApiKey()); return (TemplateResponse) request.postRequest(deleteRequest, ServiceMethods.Templates.DELETE, TemplateResponse.class); } public TemplateListResponse getTemplates(BaseMandrillRequest listRequest) throws RequestFailedException { - listRequest.setKey(request.getConfig().getApiKey()); TemplateListResponse response = new TemplateListResponse(); response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(listRequest, ServiceMethods.Templates.LIST, TemplateResponse.class, templatesListReference)).getList()); diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUrlsRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUrlsRequest.java index c2f8d69..f32306f 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUrlsRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUrlsRequest.java @@ -22,7 +22,6 @@ public class MandrillUrlsRequest { public UrlListResponse getList(BaseMandrillRequest listRequest) throws RequestFailedException { UrlListResponse response = new UrlListResponse(); - listRequest.setKey(request.getConfig().getApiKey()); response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(listRequest, ServiceMethods.Urls.LIST, UrlListResponse.class, urlsListReference)) .getList()); return response; @@ -30,14 +29,12 @@ public UrlListResponse getList(BaseMandrillRequest listRequest) throws RequestFa public UrlListResponse doSearch(MandrillRequestWithQuery searchRequest) throws RequestFailedException { UrlListResponse response = new UrlListResponse(); - searchRequest.setKey(request.getConfig().getApiKey()); response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(searchRequest, ServiceMethods.Urls.SEARCH, UrlListResponse.class, urlsListReference)) .getList()); return response; } public UrlListResponse getTimeSeries(MandrillRequestWithUrl seriesRequest) throws RequestFailedException { - seriesRequest.setKey(request.getConfig().getApiKey()); UrlListResponse response = new UrlListResponse(); response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(seriesRequest, ServiceMethods.Urls.TIME_SERIES, UrlListResponse.class, urlsListReference)).getList()); diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUsersRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUsersRequest.java index 0d7d359..a7e9abe 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUsersRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/request/MandrillUsersRequest.java @@ -41,7 +41,6 @@ public class MandrillUsersRequest { * @throws RequestFailedException */ public UsersInfoResponse getInfo(BaseMandrillRequest infoRequest) throws RequestFailedException { - infoRequest.setKey(request.getConfig().getApiKey()); BaseMandrillResponse response = request.postRequest(infoRequest, ServiceMethods.Users.INFO, UsersInfoResponse.class); return (UsersInfoResponse) response; } @@ -54,7 +53,6 @@ public UsersInfoResponse getInfo(BaseMandrillRequest infoRequest) throws Request * @throws RequestFailedException */ public BaseMandrillStringResponse performPing(BaseMandrillRequest pingRequest) throws RequestFailedException { - pingRequest.setKey(request.getConfig().getApiKey()); BaseMandrillStringResponse response = (BaseMandrillStringResponse) request.postRequest(pingRequest, ServiceMethods.Users.PING, null); return response; } @@ -67,8 +65,7 @@ public BaseMandrillStringResponse performPing(BaseMandrillRequest pingRequest) t * @throws RequestFailedException */ public PingResponse performPing2(BaseMandrillRequest pingRequest) throws RequestFailedException { - pingRequest.setKey(request.getConfig().getApiKey()); - PingResponse response = (PingResponse) request.postRequest(pingRequest, ServiceMethods.Users.PING2, PingResponse.class); + PingResponse response = (PingResponse) request.postRequest(pingRequest, ServiceMethods.Users.PING2, null); return response; } @@ -80,7 +77,6 @@ public PingResponse performPing2(BaseMandrillRequest pingRequest) throws Request * @throws RequestFailedException */ public UsersSendersResponse getSenders(BaseMandrillRequest sendersRequest) throws RequestFailedException { - sendersRequest.setKey(request.getConfig().getApiKey()); UsersSendersResponse response = new UsersSendersResponse(); response.setList(((BaseMandrillAnonymousListResponse) request.postRequest(sendersRequest, ServiceMethods.Users.SENDERS, UsersSendersResponse.class, usersListReference)).getList()); From 41254a8296cee1a1863bbbdce746208e8257f6f4 Mon Sep 17 00:00:00 2001 From: Brian Cribbs Date: Sun, 16 Jun 2013 17:18:30 -0400 Subject: [PATCH 09/11] moving javadoc to a more likely to be read location --- .../mandrill/model/BaseMandrillRequest.java | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/model/BaseMandrillRequest.java b/src/main/java/com/cribbstechnologies/clients/mandrill/model/BaseMandrillRequest.java index 30c46f6..0633702 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/model/BaseMandrillRequest.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/model/BaseMandrillRequest.java @@ -2,18 +2,20 @@ public class BaseMandrillRequest { - /* - * It's not necessary to set this field manually as the MandrillRESTRequest pulls the property - * from the configuration and populates this object with it on every request. - */ - private String key; + private String key; - public String getKey() { - return key; - } + public String getKey() { + return key; + } - public void setKey(String key) { - this.key = key; - } + /** + * It's not necessary to set this field manually as the MandrillRESTRequest pulls the property from the configuration and + * populates this object with it on every request + * + * @param key + */ + public void setKey(String key) { + this.key = key; + } } From efee98436270a06941d292e2a68a375aa27de77b Mon Sep 17 00:00:00 2001 From: Alex Dobjanschi Date: Thu, 15 Aug 2013 18:06:30 +0300 Subject: [PATCH 10/11] Compile target set to 1.5 --- pom.xml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dd0f892..fbc785d 100644 --- a/pom.xml +++ b/pom.xml @@ -64,4 +64,19 @@ - \ No newline at end of file + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.5 + 1.5 + + + + + From b8cfd1d8d1f7f8c05d3616220a562dbb4be156f8 Mon Sep 17 00:00:00 2001 From: Martin Zapata Date: Fri, 13 Sep 2013 18:08:40 +1000 Subject: [PATCH 11/11] Can now send Attachments with messages! --- .../clients/mandrill/model/Attachment.java | 44 ++++++++++++++++++ .../mandrill/model/MandrillMessage.java | 9 ++++ .../request/MandrillRESTRequestTest.java | 22 +++++++++ src/test/resources/messages/jose.jpeg | Bin 0 -> 6104 bytes 4 files changed, 75 insertions(+) create mode 100644 src/main/java/com/cribbstechnologies/clients/mandrill/model/Attachment.java create mode 100644 src/test/resources/messages/jose.jpeg diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/model/Attachment.java b/src/main/java/com/cribbstechnologies/clients/mandrill/model/Attachment.java new file mode 100644 index 0000000..bd5e5dc --- /dev/null +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/model/Attachment.java @@ -0,0 +1,44 @@ +package com.cribbstechnologies.clients.mandrill.model; + +/** + * + * @author Martin Zapata + * + */ + +public class Attachment { + + private String type, name, content; + + public Attachment(String type, String name, String content) { + this.type = type; + this.name = name; + this.content = content; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + +} diff --git a/src/main/java/com/cribbstechnologies/clients/mandrill/model/MandrillMessage.java b/src/main/java/com/cribbstechnologies/clients/mandrill/model/MandrillMessage.java index a843770..1852e92 100644 --- a/src/main/java/com/cribbstechnologies/clients/mandrill/model/MandrillMessage.java +++ b/src/main/java/com/cribbstechnologies/clients/mandrill/model/MandrillMessage.java @@ -19,6 +19,7 @@ public class MandrillMessage { private String[] google_analytics_campaign = new String[0]; private List global_merge_vars; List merge_vars; + private List attachments; private Map headers; @@ -142,4 +143,12 @@ public List getMerge_vars() { public void setMerge_vars(List merge_vars) { this.merge_vars = merge_vars; } + + public List getAttachments() { + return attachments; + } + + public void setAttachments(List attachments) { + this.attachments = attachments; + } } diff --git a/src/test/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequestTest.java b/src/test/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequestTest.java index 368668b..b6422d1 100644 --- a/src/test/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequestTest.java +++ b/src/test/java/com/cribbstechnologies/clients/mandrill/request/MandrillRESTRequestTest.java @@ -9,14 +9,23 @@ import static org.mockito.Mockito.doThrow; import static org.mockito.MockitoAnnotations.initMocks; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.net.MalformedURLException; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import javax.imageio.ImageIO; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.binary.Base64InputStream; +import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; @@ -36,6 +45,7 @@ import org.mockito.Mockito; import com.cribbstechnologies.clients.mandrill.exception.RequestFailedException; +import com.cribbstechnologies.clients.mandrill.model.Attachment; import com.cribbstechnologies.clients.mandrill.model.BaseMandrillRequest; import com.cribbstechnologies.clients.mandrill.model.MandrillHtmlMessage; import com.cribbstechnologies.clients.mandrill.model.MandrillMessageRequest; @@ -243,6 +253,10 @@ public void testGetPostDataMandrillMessageRequest() throws Exception { mutableMessage.setHeaders(headerMap); + List attachments = new ArrayList(); + attachments.add(new Attachment("image/jpeg", "jose.png", sampleBase64Image())); + mutableMessage.setAttachments(attachments); + mutableMessageRequest.setMessage(mutableMessage); // System.out.println(request.getPostData(mutableMessageRequest)); StringBuffer sb = new StringBuffer(); @@ -263,6 +277,7 @@ public void testGetPostDataMandrillMessageRequest() throws Exception { sb.append(",\"google_analytics_campaign\":[]"); sb.append(",\"global_merge_vars\":null"); sb.append(",\"merge_vars\":null"); + sb.append(",\"attachments\":[{\"type\":\"image/jpeg\",\"name\":\"jose.png\",\"content\":\"W3siZW1haWwiOiAiZXhhbXBsZSBlbWFpbCIsICJzdGF0dXMiOiAiZXhhbXBsZSBzdGF0dXMifSx7\\r\\nImVtYWlsIjogImV4YW1wbGUgZW1haWwyIiwgInN0YXR1cyI6ICJleGFtcGxlIHN0YXR1czIifV0=\\r\\n\"}]"); sb.append(",\"headers\":{\"headerName\":\"headerValue\"},"); sb.append("\"html\":\"Test html\""); sb.append("}}"); @@ -271,6 +286,13 @@ public void testGetPostDataMandrillMessageRequest() throws Exception { assertEquals(sb.toString(), output); } + private String sampleBase64Image() throws IOException { + StringWriter sw = new StringWriter(); + IOUtils.copy(new Base64InputStream(this.getClass().getClassLoader().getResourceAsStream("messages/sendMessageResponse.txt"), true), sw); + + return sw.toString(); + } + @Test public void testPostRequest() throws ClientProtocolException, IOException { request = new MandrillRESTRequest(); diff --git a/src/test/resources/messages/jose.jpeg b/src/test/resources/messages/jose.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..40551fa1699611f59a0081738f19ee5d063a88bb GIT binary patch literal 6104 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 MmAl?Sd;jhK0MesK&Hw-a literal 0 HcmV?d00001