View Javadoc

1   /**
2    * Copyright 2011 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   */
15  package org.kuali.mobility.push.factory;
16  
17  import java.security.KeyStore;
18  
19  import javax.net.ssl.KeyManagerFactory;
20  import javax.net.ssl.SSLContext;
21  import javax.net.ssl.SSLSocket;
22  import javax.net.ssl.SSLSocketFactory;
23  import javax.net.ssl.TrustManagerFactory;
24  
25  import org.apache.commons.pool.PoolableObjectFactory;
26  import org.springframework.beans.factory.annotation.Value;
27  import org.springframework.core.io.Resource;
28  
29  /**
30   * Factory that creates a pool of connection to the Apple Push Notifications Feedback Service.
31   * This Factory is used by <code>DeviceFeedbackMonitor</code> and is injected using spring configuration.
32   * 
33   * The configuration for this factory is injected via spring.
34   * 
35    * Available spring properties are:<br>
36   * <table style="border-collapse:collapse; border: 1px solid;" border="1" cellpadding="3px">
37   * 	<tr><th>Property</th><th>Purpose</th></tr>
38   *  <tr><td><code>push.apple.feedback.host</code></td><td>APNS host name</td></tr>
39   * 	<tr><td><code>push.apple.key.file</code></td><td>Path to the certificate for APNS</td></tr>
40   * 	<tr><td><code>push.apple.key.passphrase</code></td><td>Password for the certificate</td></tr>
41   * 	<tr><td><code>push.apple.feedback.port</code></td><td>Port connect to on the APNS</td></tr>
42   * </table>
43   * 
44   * @author Kuali Mobility Team (mobility.dev@kuali.org)
45   * @since 2.3.0
46   */
47  public class iOSFeedbackConnectionFactory implements PoolableObjectFactory<SSLSocket>{
48  
49  	/** APN host name */
50  	@Value("${push.apple.feedback.host}")
51  	private String host = null;
52  
53  	/** APN Host port */
54  	@Value("${push.apple.feedback.port}")
55  	private int port;
56  	
57  	/** Path to the cert for APN */
58  	@Value("${push.apple.key.file}")
59  	private Resource certPath;
60  
61  	/** Password for the APN certificate */
62  	@Value("${push.apple.key.passphrase}")
63  	private String certPassword;
64  
65  
66  
67  	/*
68  	 * (non-Javadoc)
69  	 * @see org.apache.commons.pool.PoolableObjectFactory#makeObject()
70  	 */
71  	@Override
72  	public SSLSocket makeObject() throws Exception {
73  		SSLSocket socket = null;
74  		KeyStore keyStore = KeyStore.getInstance("PKCS12");
75  		keyStore.load(certPath.getInputStream(), certPassword.toCharArray());
76  		KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("sunx509");
77  		keyManagerFactory.init(keyStore, certPassword.toCharArray());
78  		TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("sunx509");
79  		trustManagerFactory.init(keyStore);
80  		SSLContext sslCtx = SSLContext.getInstance("TLS");
81  		sslCtx.init(keyManagerFactory.getKeyManagers(), null, null);
82  		SSLSocketFactory sslSocketFactory = sslCtx.getSocketFactory();
83  		socket = (SSLSocket)sslSocketFactory.createSocket(host, port);
84  		socket.startHandshake();
85  		return socket;
86  	}
87  
88  	/*
89  	 * (non-Javadoc)
90  	 * @see org.apache.commons.pool.PoolableObjectFactory#destroyObject(java.lang.Object)
91  	 */
92  	@Override
93  	public void destroyObject(SSLSocket obj) throws Exception {
94  		if (obj == null){
95  			/* If an exception ocurred during the creation of an object
96  			 * we will receive an null object to destroy */
97  			return;
98  		}
99  		try{
100 			obj.close();
101 		}
102 		catch (Exception e) {
103 			// Don't worry - just try and close
104 		}
105 	}
106 
107 	/*
108 	 * (non-Javadoc)
109 	 * @see org.apache.commons.pool.PoolableObjectFactory#validateObject(java.lang.Object)
110 	 */
111 	@Override
112 	public boolean validateObject(SSLSocket obj) {
113 		if (obj == null){
114 			return false; // null is obviously not valid
115 		}
116 		return obj.isConnected() && !obj.isClosed();
117 	}
118 
119 	/*
120 	 * (non-Javadoc)
121 	 * @see org.apache.commons.pool.PoolableObjectFactory#activateObject(java.lang.Object)
122 	 */
123 	@Override
124 	public void activateObject(SSLSocket obj) throws Exception {
125 		// Do nothing
126 	}
127 
128 	/*
129 	 * (non-Javadoc)
130 	 * @see org.apache.commons.pool.PoolableObjectFactory#passivateObject(java.lang.Object)
131 	 */
132 	@Override
133 	public void passivateObject(SSLSocket obj) throws Exception {
134 		// Do nothing
135 	}
136 }