Skip to content

Commit 9f118a8

Browse files
updates javadocs, adds handling for 400 send request api server responses, adds possibility to pass any Object into message variables and headers
1 parent cef0bb5 commit 9f118a8

5 files changed

Lines changed: 89 additions & 10 deletions

File tree

src/main/java/com/mailjet/client/MailjetResponseUtil.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public final class MailjetResponseUtil {
1616
private static final int INTERNAL_SERVER_ERROR_STATUS = 500;
1717
private static final int BAD_REQUEST_ERROR_STATUS = 400;
1818
private static final int UNAUTHORIZED_STATUS = 401;
19+
public static final int CREATED_STATUS = 201;
1920

2021
private static final String UNAUTHORIZED_MESSAGE = "Unauthorized. Please,verify your access key and access secret key or token for the given account";
2122
private static final String TOO_MANY_REQUESTS_EXCEPTION = "Too Many Requests";
@@ -42,7 +43,7 @@ public static boolean isValidJSON(String json) {
4243
return json != null && json.trim().startsWith("{") && json.trim().endsWith("}");
4344
}
4445

45-
/*
46+
/**
4647
* Specific API methods support partial success
4748
* like, if we send multiple emails in bulk
4849
* and the one is failed and other one sent successfully
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.mailjet.client.helpers;
2+
3+
import com.google.gson.JsonElement;
4+
import com.google.gson.JsonSerializationContext;
5+
import com.google.gson.JsonSerializer;
6+
7+
import java.lang.reflect.Type;
8+
import java.util.HashMap;
9+
import java.util.Map;
10+
11+
/**
12+
* Serializes {@code Map<String, Object> as Map<String, String>}
13+
* where String value is JSON representation of the value
14+
*/
15+
public class StringMapSerializer implements JsonSerializer<Map> {
16+
@Override
17+
public JsonElement serialize(Map map, Type type, JsonSerializationContext jsonSerializationContext) {
18+
Map<String, String> stringMap = new HashMap<>(map.size());
19+
20+
for (Object entry: map.entrySet()) {
21+
Map.Entry<String, Object> objectEntry = (Map.Entry<String, Object>) entry;
22+
23+
String key = objectEntry.getKey();
24+
String value = jsonSerializationContext.serialize(objectEntry.getValue()).toString();
25+
26+
stringMap.put(key, value);
27+
}
28+
29+
return jsonSerializationContext.serialize(stringMap);
30+
}
31+
}

src/main/java/com/mailjet/client/transactional/SendEmailsRequest.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package com.mailjet.client.transactional;
22

3-
import com.google.gson.FieldNamingPolicy;
4-
import com.google.gson.Gson;
5-
import com.google.gson.GsonBuilder;
3+
import com.google.gson.*;
64
import com.mailjet.client.MailjetClient;
75
import com.mailjet.client.MailjetRequest;
86
import com.mailjet.client.MailjetResponse;
7+
import com.mailjet.client.MailjetResponseUtil;
8+
import com.mailjet.client.errors.MailjetClientRequestException;
99
import com.mailjet.client.errors.MailjetException;
1010
import com.mailjet.client.resource.Emailv31;
1111
import com.mailjet.client.transactional.response.SendEmailsResponse;
@@ -18,6 +18,10 @@
1818
@Builder
1919
public class SendEmailsRequest {
2020

21+
private final static Gson gson = new GsonBuilder()
22+
.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
23+
.create();
24+
2125
/**
2226
* Adds message to sent to the request
2327
* You can send up to 50 messages per batch
@@ -40,12 +44,12 @@ public class SendEmailsRequest {
4044
* Note: Max 50 emails per batch allowed
4145
* @param mailjetClient the Mailjet client that will be used to send messages
4246
* @return A response with sent messages information, or error information
43-
* @throws MailjetException in case of communication error
47+
* @throws MailjetException in case of communication error in HTTP stack,
48+
* like, TLS connection couldn't be established to the Mailjet server
49+
* Or the Server returned 5xx error,
50+
* Or the Server returned the generic error response
4451
*/
4552
public SendEmailsResponse sendWith(MailjetClient mailjetClient) throws MailjetException {
46-
Gson gson = new GsonBuilder()
47-
.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
48-
.create();
4953

5054
MailjetRequest request = new MailjetRequest(Emailv31.resource);
5155
request.setBody(gson.toJson(this));
@@ -56,6 +60,11 @@ public SendEmailsResponse sendWith(MailjetClient mailjetClient) throws MailjetEx
5660

5761
SendEmailsResponse typedResponse = gson.fromJson(responseContent, SendEmailsResponse.class);
5862

63+
// in some cases, Mailjet server returns generic error w/o parsing the real passed messages
64+
if (typedResponse.getMessages() == null && response.getStatus() != MailjetResponseUtil.CREATED_STATUS){
65+
throw new MailjetClientRequestException(responseContent, response.getStatus());
66+
}
67+
5968
return typedResponse;
6069
}
6170
}

src/main/java/com/mailjet/client/transactional/TransactionalEmail.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.mailjet.client.transactional;
22

3+
import com.google.gson.annotations.JsonAdapter;
34
import com.google.gson.annotations.SerializedName;
5+
import com.mailjet.client.helpers.StringMapSerializer;
46
import lombok.Builder;
57
import lombok.Singular;
68

@@ -177,16 +179,20 @@ public class TransactionalEmail {
177179

178180
/**
179181
* Additional email headers.
182+
* If the passed value type is not String, it will be serialized as a String with JSON representation of the passed object
180183
*/
181184
@Singular
182-
private Map<String, String> headers;
185+
@JsonAdapter(StringMapSerializer.class)
186+
private Map<String, Object> headers;
183187

184188
/**
185189
* Adds variable used to modify the content of your email.
186190
* Specified as {var_name}:{var_value} pairs.
191+
* If the passed value type is not String, it will be serialized as a String with JSON representation of the passed object
187192
* Enter the information in the template text / HTML part by using the [[var:{var_name}]] format.
188193
* Equivalent of using X-MJ-Vars header through SMTP.
189194
*/
190195
@Singular
191-
private Map<String, String> variables;
196+
@JsonAdapter(StringMapSerializer.class)
197+
private Map<String, Object> variables;
192198
}

src/test/java/com/mailjet/client/TransactionalEmailBuilderIT.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.mailjet.client;
22

3+
import com.mailjet.client.errors.MailjetClientRequestException;
34
import com.mailjet.client.errors.MailjetException;
45
import com.mailjet.client.transactional.*;
56
import com.mailjet.client.transactional.response.MessageResult;
@@ -12,6 +13,7 @@
1213

1314
import java.io.IOException;
1415
import java.nio.file.Paths;
16+
import java.util.LinkedList;
1517

1618

1719
public class TransactionalEmailBuilderIT {
@@ -42,6 +44,7 @@ public void SendEmailsRequest_SendsMessage() throws MailjetException, IOExceptio
4244
.trackOpens(TrackOpens.ENABLED)
4345
.attachment(Attachment.fromFile(attachmentPath))
4446
.header("test-header-key", "test-value")
47+
.variable("test-vars-array", new String[] {"a", "b", "c"})
4548
.customID("custom-id-value")
4649
.build();
4750

@@ -94,4 +97,33 @@ public void SendEmailsRequest_InvalidToField_ReturnsAnError() throws MailjetExce
9497
Assert.assertEquals("\"invalid-email\" is an invalid email address.", error.getErrorMessage());
9598
Assert.assertEquals("To[0].Email", error.getErrorRelatedTo()[0]);
9699
}
100+
101+
@Test
102+
public void SendEmailsRequest_MoreThan50MessagesPassed_ReturnsAnError() throws MailjetException, IOException {
103+
// arrange
104+
LinkedList<TransactionalEmail> messages = new LinkedList<>();
105+
106+
for (int i = 0; i < 51; i++) {
107+
TransactionalEmail message = TransactionalEmail
108+
.builder()
109+
.to(new SendContact("test@mailjet.com"))
110+
.from(new SendContact(senderEmail, "Mailjet integration test"))
111+
.htmlPart("<h1>This is the HTML content of the mail</h1>")
112+
.subject("This is the subject")
113+
.build();
114+
115+
messages.add(message);
116+
}
117+
118+
SendEmailsRequest request = SendEmailsRequest
119+
.builder()
120+
.messages(messages)
121+
.build();
122+
123+
// act
124+
MailjetClientRequestException exception = Assert.assertThrows(MailjetClientRequestException.class, () -> request.sendWith(client));
125+
126+
// assert
127+
Assert.assertTrue(exception.getMessage().contains("Total number of recipients exceeded. Max allowed - 50"));
128+
}
97129
}

0 commit comments

Comments
 (0)