Skip to content

Commit

Permalink
Support for connecting to APNs on port 2197.
Browse files Browse the repository at this point in the history
Closes #40
  • Loading branch information
judepereira committed Apr 5, 2018
1 parent d71c08e commit 192e720
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 14 deletions.
24 changes: 20 additions & 4 deletions src/main/java/com/clevertap/apns/clients/ApnsClientBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public class ApnsClientBuilder {
private InputStream certificate;
private boolean production;
private String password;
private int connectionPort = 443;

private boolean asynchronous = false;
private String defaultTopic = null;
Expand Down Expand Up @@ -92,6 +93,21 @@ public ApnsClientBuilder withOkHttpClientBuilder(OkHttpClient.Builder clientBuil
return this;
}

/**
* APNs supports connections over ports 443 and 2197.
*
* @param port Either 443 or 2197
* @return the builder
*/
public ApnsClientBuilder withPort(final int port) {
if (port != 443 && port != 2197) {
throw new IllegalArgumentException("APNs only supports ports 443 and 2197. Invalid port " + port);
}

this.connectionPort = port;
return this;
}

public ApnsClientBuilder withConnectionPool(ConnectionPool connectionPool) {
this.connectionPool = connectionPool;
return this;
Expand Down Expand Up @@ -167,15 +183,15 @@ public ApnsClient build() throws CertificateException,

if (certificate != null) {
if (asynchronous) {
return new AsyncOkHttpApnsClient(certificate, password, production, defaultTopic, builder);
return new AsyncOkHttpApnsClient(certificate, password, production, defaultTopic, builder, connectionPort);
} else {
return new SyncOkHttpApnsClient(certificate, password, production, defaultTopic, builder);
return new SyncOkHttpApnsClient(certificate, password, production, defaultTopic, builder, connectionPort);
}
} else if (keyID != null && teamID != null && apnsAuthKey != null) {
if (asynchronous) {
return new AsyncOkHttpApnsClient(apnsAuthKey, teamID, keyID, production, defaultTopic, builder);
return new AsyncOkHttpApnsClient(apnsAuthKey, teamID, keyID, production, defaultTopic, builder, connectionPort);
} else {
return new SyncOkHttpApnsClient(apnsAuthKey, teamID, keyID, production, defaultTopic, builder);
return new SyncOkHttpApnsClient(apnsAuthKey, teamID, keyID, production, defaultTopic, builder, connectionPort);
}
} else {
throw new IllegalArgumentException("Either the token credentials (team ID, key ID, and the private key) " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,25 @@ public AsyncOkHttpApnsClient(InputStream certificate, String password, boolean p

public AsyncOkHttpApnsClient(String apnsAuthKey, String teamID, String keyID,
boolean production, String defaultTopic, OkHttpClient.Builder builder) {
this(apnsAuthKey, teamID, keyID, production, defaultTopic, builder, 443);
}

public AsyncOkHttpApnsClient(String apnsAuthKey, String teamID, String keyID,
boolean production, String defaultTopic, OkHttpClient.Builder builder, int connectionPort) {
super(apnsAuthKey, teamID, keyID, production, defaultTopic, builder);
}

public AsyncOkHttpApnsClient(InputStream certificate, String password, boolean production,
String defaultTopic, OkHttpClient.Builder builder)
throws CertificateException, NoSuchAlgorithmException, KeyStoreException,
IOException, UnrecoverableKeyException, KeyManagementException {
this(certificate, password, production, defaultTopic, builder, 443);
}

public AsyncOkHttpApnsClient(InputStream certificate, String password, boolean production,
String defaultTopic, OkHttpClient.Builder builder, int connectionPort)
throws CertificateException, NoSuchAlgorithmException, KeyStoreException,
IOException, UnrecoverableKeyException, KeyManagementException {
super(certificate, password, production, defaultTopic, builder);
}

Expand Down
60 changes: 50 additions & 10 deletions src/main/java/com/clevertap/apns/clients/SyncOkHttpApnsClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,30 @@ public class SyncOkHttpApnsClient implements ApnsClient {
*/
public SyncOkHttpApnsClient(String apnsAuthKey, String teamID, String keyID, boolean production,
String defaultTopic, OkHttpClient.Builder clientBuilder) {
this(apnsAuthKey, teamID, keyID, production, defaultTopic, clientBuilder, 443);
}

/**
* Creates a new client which uses token authentication API.
*
* @param apnsAuthKey The private key - exclude -----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY-----
* @param teamID The team ID
* @param keyID The key ID (retrieved from the file name)
* @param production Whether to use the production endpoint or the sandbox endpoint
* @param defaultTopic A default topic (can be changed per message)
* @param clientBuilder An OkHttp client builder, possibly pre-initialized, to build the actual client
* @param connectionPort The port to establish a connection with APNs. Either 443 or 2197
*/
public SyncOkHttpApnsClient(String apnsAuthKey, String teamID, String keyID, boolean production,
String defaultTopic, OkHttpClient.Builder clientBuilder, int connectionPort) {
this.apnsAuthKey = apnsAuthKey;
this.teamID = teamID;
this.keyID = keyID;
client = clientBuilder.build();

this.defaultTopic = defaultTopic;

gateway = production ? Constants.ENDPOINT_PRODUCTION : Constants.ENDPOINT_SANDBOX;
gateway = (production ? Constants.ENDPOINT_PRODUCTION : Constants.ENDPOINT_SANDBOX) + ":" + connectionPort;
}

/**
Expand All @@ -103,11 +119,11 @@ public SyncOkHttpApnsClient(String apnsAuthKey, String teamID, String keyID, boo
* Creates a new client and automatically loads the key store
* with the push certificate read from the input stream.
*
* @param certificate The client certificate to be used
* @param password The password (if required, else null)
* @param production Whether to use the production endpoint or the sandbox endpoint
* @param defaultTopic A default topic (can be changed per message)
* @param builder An OkHttp client builder, possibly pre-initialized, to build the actual client
* @param certificate The client certificate to be used
* @param password The password (if required, else null)
* @param production Whether to use the production endpoint or the sandbox endpoint
* @param defaultTopic A default topic (can be changed per message)
* @param builder An OkHttp client builder, possibly pre-initialized, to build the actual client
* @throws UnrecoverableKeyException If the key cannot be recovered
* @throws KeyManagementException if the key failed to be loaded
* @throws CertificateException if any of the certificates in the keystore could not be loaded
Expand All @@ -120,6 +136,31 @@ public SyncOkHttpApnsClient(InputStream certificate, String password, boolean pr
String defaultTopic, OkHttpClient.Builder builder)
throws CertificateException, NoSuchAlgorithmException, KeyStoreException,
IOException, UnrecoverableKeyException, KeyManagementException {
this(certificate, password, production, defaultTopic, builder, 443);
}

/**
* Creates a new client and automatically loads the key store
* with the push certificate read from the input stream.
*
* @param certificate The client certificate to be used
* @param password The password (if required, else null)
* @param production Whether to use the production endpoint or the sandbox endpoint
* @param defaultTopic A default topic (can be changed per message)
* @param builder An OkHttp client builder, possibly pre-initialized, to build the actual client
* @param connectionPort The port to establish a connection with APNs. Either 443 or 2197
* @throws UnrecoverableKeyException If the key cannot be recovered
* @throws KeyManagementException if the key failed to be loaded
* @throws CertificateException if any of the certificates in the keystore could not be loaded
* @throws NoSuchAlgorithmException if the algorithm used to check the integrity of the keystore cannot be found
* @throws IOException if there is an I/O or format problem with the keystore data,
* if a password is required but not given, or if the given password was incorrect
* @throws KeyStoreException if no Provider supports a KeyStoreSpi implementation for the specified type
*/
public SyncOkHttpApnsClient(InputStream certificate, String password, boolean production,
String defaultTopic, OkHttpClient.Builder builder, int connectionPort)
throws CertificateException, NoSuchAlgorithmException, KeyStoreException,
IOException, UnrecoverableKeyException, KeyManagementException {

teamID = keyID = apnsAuthKey = null;

Expand All @@ -146,7 +187,7 @@ public SyncOkHttpApnsClient(InputStream certificate, String password, boolean pr
client = builder.build();

this.defaultTopic = defaultTopic;
gateway = production ? Constants.ENDPOINT_PRODUCTION : Constants.ENDPOINT_SANDBOX;
gateway = (production ? Constants.ENDPOINT_PRODUCTION : Constants.ENDPOINT_SANDBOX) + ":" + connectionPort;
}

/**
Expand Down Expand Up @@ -209,7 +250,6 @@ protected final Request buildRequest(Notification notification) {
final Notification.Priority priority = notification.getPriority();
Request.Builder rb = new Request.Builder()
.url(gateway + "/3/device/" + notification.getToken())

.post(new RequestBody() {
@Override
public MediaType contentType() {
Expand All @@ -232,15 +272,15 @@ public void writeTo(BufferedSink sink) throws IOException {
}

if (uuid != null) {
rb.header("apns-id",uuid.toString());
rb.header("apns-id", uuid.toString());
}

if (expiration > -1) {
rb.header("apns-expiration", String.valueOf(expiration));
}

if (priority != null) {
rb.header("apns-priority",String.valueOf(priority.getCode()));
rb.header("apns-priority", String.valueOf(priority.getCode()));
}

if (keyID != null && teamID != null && apnsAuthKey != null) {
Expand Down

0 comments on commit 192e720

Please sign in to comment.