Skip to content

Commit

Permalink
DEVEXP-615: SinchClient for mailgun (#165)
Browse files Browse the repository at this point in the history
* feat (Mailgun): Initial Mailgun configuration and authentication
  • Loading branch information
JPPortier authored Oct 18, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 972f108 commit 8e50399
Showing 18 changed files with 707 additions and 3 deletions.
4 changes: 4 additions & 0 deletions client/resources/config-default.properties
Original file line number Diff line number Diff line change
@@ -22,3 +22,7 @@ conversation-region=us
conversation-server=https://%s.conversation.api.sinch.com
template-management-conversation-server=https://%s.template.api.sinch.com

mailgun-user=api
mailgun-default-server=https://api.mailgun.net
mailgun-region-server=https://api.%s.mailgun.net
mailgun-region=
59 changes: 58 additions & 1 deletion client/src/main/com/sinch/sdk/SinchClient.java
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

import com.sinch.sdk.core.utils.StringUtil;
import com.sinch.sdk.domains.conversation.ConversationService;
import com.sinch.sdk.domains.mailgun.MailgunService;
import com.sinch.sdk.domains.numbers.NumbersService;
import com.sinch.sdk.domains.sms.SMSService;
import com.sinch.sdk.domains.verification.VerificationService;
@@ -10,6 +11,8 @@
import com.sinch.sdk.models.Configuration;
import com.sinch.sdk.models.ConversationContext;
import com.sinch.sdk.models.ConversationRegion;
import com.sinch.sdk.models.MailgunContext;
import com.sinch.sdk.models.MailgunRegion;
import com.sinch.sdk.models.NumbersContext;
import com.sinch.sdk.models.SMSRegion;
import com.sinch.sdk.models.SmsContext;
@@ -48,6 +51,10 @@ public class SinchClient {
private static final String CONVERSATION_TEMPLATE_SERVER_KEY =
"template-management-conversation-server";

private static final String MAILGUN_REGION_KEY = "mailgun-region";
private static final String MAILGUN_DEFAULT_SERVER_KEY = "mailgun-default-server";
private static final String MAILGUN_REGION_SERVER_KEY = "mailgun-region-server";

// sinch-sdk/{sdk_version} ({language}/{language_version}; {implementation_type};
// {auxiliary_flag})
private static final String SDK_USER_AGENT_HEADER = "User-Agent";
@@ -61,7 +68,7 @@ public class SinchClient {
private VerificationService verification;
private VoiceService voice;
private ConversationService conversation;

private MailgunService mailgun;
private HttpClientApache httpClient;

/**
@@ -84,6 +91,7 @@ public SinchClient(Configuration configuration) {
handleDefaultVerificationSettings(configuration, props, builder);
handleDefaultVoiceSettings(configuration, props, builder);
handleDefaultConversationSettings(configuration, props, builder);
handleDefaultMailgunSettings(configuration, props, builder);

Configuration newConfiguration = builder.build();
checkConfiguration(newConfiguration);
@@ -227,6 +235,34 @@ private void handleDefaultConversationSettings(
}
}

private void handleDefaultMailgunSettings(
Configuration configuration, Properties props, Configuration.Builder builder) {

MailgunRegion region =
configuration.getMailgunContext().map(MailgunContext::getRegion).orElse(null);
// default region to be used ?
if (null == region && props.containsKey(MAILGUN_REGION_KEY)) {
String value = props.getProperty(MAILGUN_REGION_KEY);
if (!StringUtil.isEmpty(value)) {
region = MailgunRegion.from(value);
}
}

String url = configuration.getMailgunContext().map(MailgunContext::getUrl).orElse(null);

// server is not defined: use the region to set to an existing one and use "global" as a default
// fallback
if (StringUtil.isEmpty(url)) {
if (null == region || MailgunRegion.US.value().equals(region.value().toLowerCase())) {
url = props.getProperty(MAILGUN_DEFAULT_SERVER_KEY);
} else {
url = String.format(props.getProperty(MAILGUN_REGION_SERVER_KEY), region.value());
}
}

builder.setMailgunContext(MailgunContext.builder().setUrl(url).build());
}

/**
* Get current configuration
*
@@ -312,6 +348,20 @@ public ConversationService conversation() {
return conversation;
}

/**
* Get Mailgun domain service
*
* @return Return instance onto Mailgun API service
* @see <a href="__TO_BE_DEFINED__">__TO_BE_DEFINED__</a>
* @since __TO_BE_DEFINED__
*/
public MailgunService mailgun() {
if (null == mailgun) {
mailgun = mailgunInit();
}
return mailgun;
}

private void checkConfiguration(Configuration configuration) throws NullPointerException {
Objects.requireNonNull(configuration.getOAuthUrl(), "'oauthUrl' cannot be null");
}
@@ -362,6 +412,13 @@ private ConversationService conversationInit() {
getHttpClient());
}

private MailgunService mailgunInit() {
return new com.sinch.sdk.domains.mailgun.adapters.MailgunService(
getConfiguration().getMailgunCredentials().orElse(null),
getConfiguration().getMailgunContext().orElse(null),
getHttpClient());
}

private Properties handlePropertiesFile(String fileName) {

Properties prop = new Properties();
20 changes: 20 additions & 0 deletions client/src/main/com/sinch/sdk/domains/mailgun/MailgunService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.sinch.sdk.domains.mailgun;

/**
* Mailgun Service
*
* @see <a
* href="https://documentation.mailgun.com/docs/mailgun/">https://documentation.mailgun.com/docs/mailgun</a>
* @since __TO_BE_DEFINED__
*/
public interface MailgunService {

/**
* Mailgun Service V1
*
* @return V1 service instance for project
* @see <a href="__TO_BE_DEFINED__">__TO_BE_DEFINED__</a>
* @since __TO_BE_DEFINED__
*/
com.sinch.sdk.domains.mailgun.api.v1.MailgunService v1();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.sinch.sdk.domains.mailgun.adapters;

import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.domains.conversation.api.templates.adapters.TemplatesService;
import com.sinch.sdk.models.MailgunContext;
import com.sinch.sdk.models.MailgunCredentials;

public class MailgunService implements com.sinch.sdk.domains.mailgun.MailgunService {

private final MailgunCredentials credentials;
private final MailgunContext context;
private final HttpClient httpClient;

private com.sinch.sdk.domains.mailgun.api.v1.MailgunService mailgunV1;
private TemplatesService templates;

public MailgunService(
MailgunCredentials credentials, MailgunContext context, HttpClient httpClient) {
this.credentials = credentials;
this.context = context;
this.httpClient = httpClient;
}

public com.sinch.sdk.domains.mailgun.api.v1.MailgunService v1() {
if (null == this.mailgunV1) {
this.mailgunV1 =
new com.sinch.sdk.domains.mailgun.api.v1.adapters.MailgunService(
credentials, context, httpClient);
}
return this.mailgunV1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.sinch.sdk.domains.mailgun.api.v1;

/**
* Mailgun Service V1
*
* @see <a href="__TO_BE_DEFINED__">__TO_BE_DEFINED__</a>
* @since __TO_BE_DEFINED__
*/
public interface MailgunService {

/**
* Messages Service instance
*
* @return service instance for project
* @since __TO_BE_DEFINED__
*/
MessagesService messages();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.sinch.sdk.domains.mailgun.api.v1;

/**
* Mailgun Message Service V1
*
* @see <a href="__TO_BE_DEFINED__">__TO_BE_DEFINED__</a>
* @since __TO_BE_DEFINED__
*/
public interface MessagesService {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.sinch.sdk.domains.mailgun.api.v1.adapters;

import com.sinch.sdk.auth.adapters.BasicAuthManager;
import com.sinch.sdk.core.http.AuthManager;
import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.core.utils.StringUtil;
import com.sinch.sdk.models.MailgunContext;
import com.sinch.sdk.models.MailgunCredentials;
import java.util.AbstractMap;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class MailgunService implements com.sinch.sdk.domains.mailgun.api.v1.MailgunService {

private static final Logger LOGGER = Logger.getLogger(MailgunService.class.getName());
private static final String SECURITY_SCHEME_KEYWORD_NUMBERS = "BasicAuth";

private final MailgunContext context;
private final HttpClient httpClient;

private final Map<String, AuthManager> authManagers;

private MessagesService messages;

public MailgunService(
MailgunCredentials credentials, MailgunContext context, HttpClient httpClient) {

Objects.requireNonNull(credentials, "Mailgun service require credentials to be defined");
Objects.requireNonNull(context, "Mailgun service requires context to be defined");
StringUtil.requireNonEmpty(
credentials.getApiUser(), "Mailgun service requires 'apiUser' to be defined");
StringUtil.requireNonEmpty(
credentials.getApiKey(), "Mailgun service requires 'apiKey' to be defined");
StringUtil.requireNonEmpty(
context.getUrl(), "'Mailgun service requires mailgunUrl' to be defined");

LOGGER.fine("Activate Mailgun API with server='" + context.getServer().getUrl() + "'");

this.context = context;
this.httpClient = httpClient;

AuthManager basicAuthManager =
new BasicAuthManager(credentials.getApiUser(), credentials.getApiKey());

authManagers =
Stream.of(new AbstractMap.SimpleEntry<>(SECURITY_SCHEME_KEYWORD_NUMBERS, basicAuthManager))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

public MessagesService messages() {
if (null == this.messages) {
this.messages = new MessagesService(context, httpClient, authManagers);
}
return this.messages;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.sinch.sdk.domains.mailgun.api.v1.adapters;

import com.sinch.sdk.core.http.AuthManager;
import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.models.MailgunContext;
import java.util.Map;

public class MessagesService implements com.sinch.sdk.domains.mailgun.api.v1.MessagesService {

public MessagesService(
MailgunContext context, HttpClient httpClient, Map<String, AuthManager> authManagers) {}
}
11 changes: 11 additions & 0 deletions client/src/main/com/sinch/sdk/domains/mailgun/package-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Conversation API interface
*
* <p>The Sinch Conversation API allows you to send and receive messages globally over SMS, RCS,
* WhatsApp, Viber Business, Facebook Messenger and other popular channels.
*
* @see <a
* href="https://developers.sinch.com/docs/conversation">https://developers.sinch.com/docs/conversation</a>
* @since 1.3
*/
package com.sinch.sdk.domains.mailgun;
Loading

0 comments on commit 8e50399

Please sign in to comment.