Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.clevertap.apns</groupId>
<artifactId>apns-http2</artifactId>
<version>1.0.3</version>
<version>1.0.4</version>

<name>apns-http2</name>
<description>A library for communicating with the Apple Push Gateway in HTTP/2.</description>
Expand Down
37 changes: 32 additions & 5 deletions src/main/java/com/clevertap/apns/clients/ApnsClientBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
public class ApnsClientBuilder {
private InputStream certificate;
private boolean production;
/**
* gateway field should be filled for development purposes only, and contain the address of local APNS mock instance.
*/
private String customGateway;
private String password;
private int connectionPort = 443;

Expand Down Expand Up @@ -138,18 +142,25 @@ public ApnsClientBuilder withKeyID(String keyID) {
return this;
}

public ApnsClientBuilder withCustomGateway(String customGateway) {
this.customGateway = customGateway;
this.production = false;
return this;
}

public ApnsClientBuilder withProductionGateway() {
this.customGateway = null;
this.production = true;
return this;
}

public ApnsClientBuilder withProductionGateway(boolean production) {
if (production) return withProductionGateway();

return withDevelopmentGateway();
}

public ApnsClientBuilder withDevelopmentGateway() {
this.customGateway = null;
this.production = false;
return this;
}
Expand Down Expand Up @@ -183,15 +194,31 @@ public ApnsClient build() throws CertificateException,

if (certificate != null) {
if (asynchronous) {
return new AsyncOkHttpApnsClient(certificate, password, production, defaultTopic, builder, connectionPort);
if (customGateway != null){
return new AsyncOkHttpApnsClient(certificate, password, customGateway, defaultTopic, builder, connectionPort);
} else {
return new AsyncOkHttpApnsClient(certificate, password, production, defaultTopic, builder, connectionPort);
}
} else {
return new SyncOkHttpApnsClient(certificate, password, production, defaultTopic, builder, connectionPort);
if (customGateway != null){
return new SyncOkHttpApnsClient(certificate, password, customGateway, defaultTopic, builder, connectionPort);
} else {
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, connectionPort);
if (customGateway != null) {
return new AsyncOkHttpApnsClient(apnsAuthKey, teamID, keyID, customGateway, defaultTopic, builder, connectionPort);
} else {
return new AsyncOkHttpApnsClient(apnsAuthKey, teamID, keyID, production, defaultTopic, builder, connectionPort);
}
} else {
return new SyncOkHttpApnsClient(apnsAuthKey, teamID, keyID, production, defaultTopic, builder, connectionPort);
if (customGateway != null) {
return new SyncOkHttpApnsClient(apnsAuthKey, teamID, keyID, customGateway, defaultTopic, builder, connectionPort);
} else {
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 @@ -60,6 +60,13 @@ public AsyncOkHttpApnsClient(InputStream certificate, String password, boolean p
super(certificate, password, production, defaultTopic, connectionPool);
}

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

public AsyncOkHttpApnsClient(String apnsAuthKey, String teamID, String keyID,
boolean production, String defaultTopic, OkHttpClient.Builder builder) {
this(apnsAuthKey, teamID, keyID, production, defaultTopic, builder, 443);
Expand All @@ -70,6 +77,11 @@ public AsyncOkHttpApnsClient(String apnsAuthKey, String teamID, String keyID,
super(apnsAuthKey, teamID, keyID, production, defaultTopic, builder);
}

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

public AsyncOkHttpApnsClient(InputStream certificate, String password, boolean production,
String defaultTopic, OkHttpClient.Builder builder)
throws CertificateException, NoSuchAlgorithmException, KeyStoreException,
Expand Down
71 changes: 69 additions & 2 deletions src/main/java/com/clevertap/apns/clients/SyncOkHttpApnsClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,31 @@ public SyncOkHttpApnsClient(String apnsAuthKey, String teamID, String keyID, boo
*/
public SyncOkHttpApnsClient(String apnsAuthKey, String teamID, String keyID, boolean production,
String defaultTopic, OkHttpClient.Builder clientBuilder, int connectionPort) {
this (apnsAuthKey, teamID, keyID, production ? Constants.ENDPOINT_PRODUCTION : Constants.ENDPOINT_SANDBOX,
defaultTopic,clientBuilder, connectionPort);
}

/**
* 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 gateway Endpoint address
* @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, String gateway,
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) + ":" + connectionPort;
this.gateway = gateway + ":" + connectionPort;
}

/**
Expand Down Expand Up @@ -161,7 +178,6 @@ public SyncOkHttpApnsClient(InputStream certificate, String password, boolean pr
String defaultTopic, OkHttpClient.Builder builder, int connectionPort)
throws CertificateException, NoSuchAlgorithmException, KeyStoreException,
IOException, UnrecoverableKeyException, KeyManagementException {

teamID = keyID = apnsAuthKey = null;

password = password == null ? "" : password;
Expand Down Expand Up @@ -190,6 +206,57 @@ public SyncOkHttpApnsClient(InputStream certificate, String password, boolean pr
gateway = (production ? Constants.ENDPOINT_PRODUCTION : Constants.ENDPOINT_SANDBOX) + ":" + connectionPort;
}

/**
* Creates a new client for custom endpoint and automatically loads the key store
* with the push certificate read from the input stream.
* Certificate will not be validated
*
* @param certificate The client certificate to be used
* @param password The password (if required, else null)
* @param gateway Address of custom gateway.
* @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, String gateway,
String defaultTopic, OkHttpClient.Builder builder, int connectionPort)
throws CertificateException, NoSuchAlgorithmException, KeyStoreException,
IOException, UnrecoverableKeyException, KeyManagementException {

teamID = keyID = apnsAuthKey = null;

password = password == null ? "" : password;
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(certificate, password.toCharArray());

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, password.toCharArray());
KeyManager[] keyManagers = kmf.getKeyManagers();
SSLContext sslContext = SSLContext.getInstance("TLS");

final TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init((KeyStore) null);
sslContext.init(keyManagers, tmf.getTrustManagers(), null);

final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

builder.sslSocketFactory(sslSocketFactory);

client = builder.build();

this.defaultTopic = defaultTopic;
this.gateway = gateway + ":" + connectionPort;

}

/**
* Creates a new client and automatically loads the key store
* with the push certificate read from the input stream.
Expand Down