Browse Source

Use PoolingHttpClientConnectionManager to handle postback persistent connections

to Portal.
tags/before_postback_reorg
ymlam 6 years ago
parent
commit
2ac4151c04
2 changed files with 69 additions and 13 deletions
  1. +10
    -3
      src/main/java/altk/comm/engine/CommEngine.java
  2. +59
    -10
      src/main/java/altk/comm/engine/postback/PostBack.java

+ 10
- 3
src/main/java/altk/comm/engine/CommEngine.java View File

@@ -5,6 +5,9 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -587,15 +590,19 @@ public abstract class CommEngine extends HttpServlet
*/ */
abstract protected void destroyChild(); abstract protected void destroyChild();


public PostBack getPostBack(String postBackURL, String broadcastType)
public PostBack getPostBack(String postBackURL, String broadcastType) throws BroadcastException
{ {
if (postBackURL == null) return null; if (postBackURL == null) return null;


PostBack postBack = postBackMap.get(postBackURL); PostBack postBack = postBackMap.get(postBackURL);
if (postBack != null) return postBack; if (postBack != null) return postBack;
postBack = new PostBack(postBackURL, broadcastType + "_status",
postbackMaxQueueSize, postbackSenderPoolSize, postbackMaxBatchSize);
try {
postBack = new PostBack(postBackURL, broadcastType + "_status",
postbackMaxQueueSize, postbackSenderPoolSize, postbackMaxBatchSize);
} catch (KeyManagementException | IllegalArgumentException | NoSuchAlgorithmException | KeyStoreException e) {
throw new BroadcastException(BroadcastError.PLATFORM_ERROR, e.getMessage(), e);
}
postBackMap.put(postBackURL, postBack); postBackMap.put(postBackURL, postBack);
return postBack; return postBack;
} }


+ 59
- 10
src/main/java/altk/comm/engine/postback/PostBack.java View File

@@ -21,6 +21,7 @@ import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory; import javax.xml.xpath.XPathFactory;


import org.apache.http.StatusLine; import org.apache.http.StatusLine;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.NoopHostnameVerifier;
@@ -29,7 +30,9 @@ import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@@ -57,6 +60,8 @@ public class PostBack
private static final int QUEUE_WAIT = 300; // seconds private static final int QUEUE_WAIT = 300; // seconds
private static final int POSTBACK_SERVER_WAIT_TIME = 10; // seconds private static final int POSTBACK_SERVER_WAIT_TIME = 10; // seconds

private static final int RETRIES_DEFAULT = 3;
private final String postBackURL; private final String postBackURL;
private final String xmlTopElement; private final String xmlTopElement;
@@ -66,7 +71,16 @@ public class PostBack
private final String myName; private final String myName;
private int maxBatchSize; private int maxBatchSize;


private PoolingHttpClientConnectionManager cm;
private int threadsWaitingToPost; private int threadsWaitingToPost;
private TrustStrategy tustAllCerts;
SSLContext sslContext;
SSLConnectionSocketFactory connectionFactory;
CloseableHttpClient httpclient;

private int maxRetries;




private static Logger myLogger = Logger.getLogger(PostBack.class); private static Logger myLogger = Logger.getLogger(PostBack.class);


@@ -82,6 +96,7 @@ public class PostBack
{ {
private boolean threadShouldStop; private boolean threadShouldStop;



private Sender(String name) private Sender(String name)
{ {
setName(name); setName(name);
@@ -192,16 +207,12 @@ public class PostBack
} }
xml.append("</"); xml.append(xmlTopElement); xml.append(">"); xml.append("</"); xml.append(xmlTopElement); xml.append(">");
TrustStrategy tustAllCerts = new TrustStrategy() { public boolean isTrusted(X509Certificate[] chain, String authType) { return true; } };
HttpPost httpPost = new HttpPost(postBackURL); HttpPost httpPost = new HttpPost(postBackURL);
StringEntity requestEntity; StringEntity requestEntity;
CloseableHttpResponse response = null; CloseableHttpResponse response = null;
byte[] xmlBytes = null; byte[] xmlBytes = null;
try try
{ {
SSLContext sslContext = SSLContextBuilder.create().loadTrustMaterial(tustAllCerts).build();
SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
CloseableHttpClient httpclient = HttpClientBuilder.create().setSSLSocketFactory(connectionFactory).build();
requestEntity = (new StringEntity(xml.toString())); requestEntity = (new StringEntity(xml.toString()));
httpPost.setEntity(requestEntity); httpPost.setEntity(requestEntity);
myLogger.debug("Posting to " + postBackURL + ": " + xml); myLogger.debug("Posting to " + postBackURL + ": " + xml);
@@ -224,11 +235,7 @@ public class PostBack
CommonLogger.alarm.error("While posting back to broadcast requester: " + e); CommonLogger.alarm.error("While posting back to broadcast requester: " + e);
return PostBackStatus.IRRECOVERABLE_ERROR; return PostBackStatus.IRRECOVERABLE_ERROR;
} }
catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e)
{
CommonLogger.alarm.error("Totally unexpected. While constructing HttpClient for posting back to broadcast requester: " + e);
return PostBackStatus.IRRECOVERABLE_ERROR;
}


String xmlStr; String xmlStr;
try try
@@ -317,10 +324,13 @@ public class PostBack
* @param xmlTopElementName * @param xmlTopElementName
* @throws IllegalArgumentException if either postBackURL or xmlTopElementName is * @throws IllegalArgumentException if either postBackURL or xmlTopElementName is
* not supplied nor valid. * not supplied nor valid.
* @throws KeyStoreException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/ */
public PostBack(String postBackURL, String xmlTopElementName, public PostBack(String postBackURL, String xmlTopElementName,
int maxQueueSize, int senderPoolSize, int maxBatchSize) int maxQueueSize, int senderPoolSize, int maxBatchSize)
throws IllegalArgumentException
throws IllegalArgumentException, KeyManagementException, NoSuchAlgorithmException, KeyStoreException
{ {
if (postBackURL == null || postBackURL.length() == 0) if (postBackURL == null || postBackURL.length() == 0)
{ {
@@ -337,7 +347,36 @@ public class PostBack
this.maxBatchSize = maxBatchSize; this.maxBatchSize = maxBatchSize;
postQueue = new LinkedList<String>(); postQueue = new LinkedList<String>();
threadsWaitingToPost = 0; threadsWaitingToPost = 0;
cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(senderPoolSize);
cm.setDefaultMaxPerRoute(senderPoolSize);
tustAllCerts = new TrustStrategy() { public boolean isTrusted(X509Certificate[] chain, String authType) { return true; } };
sslContext = SSLContextBuilder.create().loadTrustMaterial(tustAllCerts).build();
connectionFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
//
// Retry handler
maxRetries = RETRIES_DEFAULT;
HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler()
{
public boolean retryRequest(
IOException exception,
int executionCount,
HttpContext context)
{
if (executionCount >= maxRetries) return false;
return true;
}
};

httpclient = HttpClientBuilder.create()
// .setConnectionManager(cm)
// .setRetryHandler(retryHandler)
.setSSLSocketFactory(connectionFactory)
.build();

senderPool = new ArrayList<Sender>(); senderPool = new ArrayList<Sender>();
for (int i = 0; i < senderPoolSize; i++) for (int i = 0; i < senderPoolSize; i++)
{ {
@@ -393,6 +432,16 @@ public class PostBack


public void terminate() public void terminate()
{ {
try
{
httpclient.close();
}
catch (IOException e)
{
myLogger.error("Caught when closing HttpClient: " + e.getMessage());
}
// Terminate postback threads
for (Sender sender : senderPool) for (Sender sender : senderPool)
{ {
sender.terminate(); sender.terminate();


Loading…
Cancel
Save