|
|
@@ -3,11 +3,16 @@ package altk.comm.engine.postback; |
|
|
import java.io.ByteArrayInputStream; |
|
|
import java.io.ByteArrayInputStream; |
|
|
import java.io.IOException; |
|
|
import java.io.IOException; |
|
|
import java.io.UnsupportedEncodingException; |
|
|
import java.io.UnsupportedEncodingException; |
|
|
|
|
|
import java.security.KeyManagementException; |
|
|
|
|
|
import java.security.KeyStoreException; |
|
|
|
|
|
import java.security.NoSuchAlgorithmException; |
|
|
|
|
|
import java.security.cert.X509Certificate; |
|
|
import java.util.ArrayList; |
|
|
import java.util.ArrayList; |
|
|
import java.util.LinkedList; |
|
|
import java.util.LinkedList; |
|
|
import java.util.List; |
|
|
import java.util.List; |
|
|
import java.util.Queue; |
|
|
import java.util.Queue; |
|
|
|
|
|
|
|
|
|
|
|
import javax.net.ssl.SSLContext; |
|
|
import javax.xml.parsers.DocumentBuilder; |
|
|
import javax.xml.parsers.DocumentBuilder; |
|
|
import javax.xml.parsers.DocumentBuilderFactory; |
|
|
import javax.xml.parsers.DocumentBuilderFactory; |
|
|
import javax.xml.xpath.XPath; |
|
|
import javax.xml.xpath.XPath; |
|
|
@@ -15,14 +20,18 @@ import javax.xml.xpath.XPathConstants; |
|
|
import javax.xml.xpath.XPathExpressionException; |
|
|
import javax.xml.xpath.XPathExpressionException; |
|
|
import javax.xml.xpath.XPathFactory; |
|
|
import javax.xml.xpath.XPathFactory; |
|
|
|
|
|
|
|
|
import org.apache.commons.httpclient.ConnectTimeoutException; |
|
|
|
|
|
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler; |
|
|
|
|
|
import org.apache.commons.httpclient.Header; |
|
|
|
|
|
import org.apache.commons.httpclient.HttpClient; |
|
|
|
|
|
import org.apache.commons.httpclient.HttpURL; |
|
|
|
|
|
import org.apache.commons.httpclient.methods.PostMethod; |
|
|
|
|
|
import org.apache.commons.httpclient.methods.StringRequestEntity; |
|
|
|
|
|
import org.apache.commons.httpclient.params.HttpMethodParams; |
|
|
|
|
|
|
|
|
import org.apache.http.StatusLine; |
|
|
|
|
|
import org.apache.http.client.methods.CloseableHttpResponse; |
|
|
|
|
|
import org.apache.http.client.methods.HttpPost; |
|
|
|
|
|
import org.apache.http.conn.ssl.NoopHostnameVerifier; |
|
|
|
|
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
|
|
|
|
|
import org.apache.http.conn.ssl.TrustStrategy; |
|
|
|
|
|
import org.apache.http.entity.StringEntity; |
|
|
|
|
|
import org.apache.http.impl.client.CloseableHttpClient; |
|
|
|
|
|
import org.apache.http.impl.client.HttpClientBuilder; |
|
|
|
|
|
import org.apache.http.protocol.BasicHttpContext; |
|
|
|
|
|
import org.apache.http.ssl.SSLContextBuilder; |
|
|
|
|
|
import org.apache.http.util.EntityUtils; |
|
|
import org.apache.log4j.Logger; |
|
|
import org.apache.log4j.Logger; |
|
|
import org.w3c.dom.Document; |
|
|
import org.w3c.dom.Document; |
|
|
import org.w3c.dom.Node; |
|
|
import org.w3c.dom.Node; |
|
|
@@ -183,110 +192,72 @@ public class PostBack |
|
|
} |
|
|
} |
|
|
xml.append("</"); xml.append(xmlTopElement); xml.append(">"); |
|
|
xml.append("</"); xml.append(xmlTopElement); xml.append(">"); |
|
|
|
|
|
|
|
|
PostMethod post = new PostMethod(); |
|
|
|
|
|
String responseBody = null; |
|
|
|
|
|
StringRequestEntity requestEntity = null; |
|
|
|
|
|
|
|
|
TrustStrategy tustAllCerts = new TrustStrategy() { public boolean isTrusted(X509Certificate[] chain, String authType) { return true; } }; |
|
|
|
|
|
HttpPost httpPost = new HttpPost(postBackURL); |
|
|
|
|
|
StringEntity requestEntity; |
|
|
|
|
|
CloseableHttpResponse response = null; |
|
|
|
|
|
byte[] xmlBytes = null; |
|
|
try |
|
|
try |
|
|
{ |
|
|
{ |
|
|
requestEntity = new StringRequestEntity(xml.toString(), "application/xml", "utf-8"); |
|
|
|
|
|
|
|
|
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())); |
|
|
|
|
|
httpPost.setEntity(requestEntity); |
|
|
|
|
|
myLogger.debug("Posting to " + postBackURL + ": " + xml); |
|
|
|
|
|
response = httpclient.execute(httpPost, new BasicHttpContext()); |
|
|
|
|
|
StatusLine statusLine = response.getStatusLine(); |
|
|
|
|
|
int statusCode = statusLine.getStatusCode(); |
|
|
|
|
|
if (statusCode != 200) |
|
|
|
|
|
{ |
|
|
|
|
|
CommonLogger.alarm.error("Got error status code " + statusCode + " while posting status to broadcast requester"); |
|
|
|
|
|
return PostBackStatus.HTTP_STATUS_ERROR; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
catch (UnsupportedEncodingException e) |
|
|
catch (UnsupportedEncodingException e) |
|
|
{ |
|
|
{ |
|
|
CommonLogger.alarm.warn("While adding this application/xml content to PostBack: " + xml + " -- " + e); |
|
|
CommonLogger.alarm.warn("While adding this application/xml content to PostBack: " + xml + " -- " + e); |
|
|
return PostBackStatus.IRRECOVERABLE_ERROR; |
|
|
return PostBackStatus.IRRECOVERABLE_ERROR; |
|
|
} |
|
|
} |
|
|
post.setRequestEntity(requestEntity); |
|
|
|
|
|
post.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, |
|
|
|
|
|
new DefaultHttpMethodRetryHandler(3, false)); |
|
|
|
|
|
/* |
|
|
|
|
|
CommonLogger.activity.debug("Before calling setFolloweRedirects()"); |
|
|
|
|
|
post.setFollowRedirects(false); |
|
|
|
|
|
CommonLogger.activity.debug("After calling setFolloweRedirects()"); |
|
|
|
|
|
*/ |
|
|
|
|
|
HttpClient client = new HttpClient(); |
|
|
|
|
|
String url = postBackURL; |
|
|
|
|
|
for (int redirectCount = 0; redirectCount < 3; redirectCount++) |
|
|
|
|
|
|
|
|
catch (IOException e) |
|
|
{ |
|
|
{ |
|
|
try |
|
|
|
|
|
{ |
|
|
|
|
|
client.getHttpConnectionManager().getParams().setConnectionTimeout(5 * 1000); |
|
|
|
|
|
post.setURI(new HttpURL(url)); |
|
|
|
|
|
if (redirectCount == 0) |
|
|
|
|
|
{ |
|
|
|
|
|
CommonLogger.activity.info("posting " + xml.toString() + " to " + url); |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
CommonLogger.activity.info("redirected to " + url); |
|
|
|
|
|
} |
|
|
|
|
|
long beginPost = System.currentTimeMillis(); |
|
|
|
|
|
int statusCode = client.executeMethod(post); |
|
|
|
|
|
long postingTime = System.currentTimeMillis() - beginPost; // msec |
|
|
|
|
|
|
|
|
|
|
|
if (statusCode == 302) |
|
|
|
|
|
{ |
|
|
|
|
|
Header locationHeader = post.getResponseHeader("Location"); |
|
|
|
|
|
if (locationHeader != null) |
|
|
|
|
|
{ |
|
|
|
|
|
url = locationHeader.getValue(); |
|
|
|
|
|
post.releaseConnection(); |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
CommonLogger.alarm.warn("When posting to \"" + url + "\": " + " received status 302 but without location header"); |
|
|
|
|
|
return PostBackStatus.IRRECOVERABLE_ERROR; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
else if (statusCode != 200) |
|
|
|
|
|
{ |
|
|
|
|
|
CommonLogger.alarm.warn("Received problem status code " + statusCode + " from posting to \"" + url + "\": " + xml); |
|
|
|
|
|
return PostBackStatus.HTTP_STATUS_ERROR; |
|
|
|
|
|
} |
|
|
|
|
|
responseBody = post.getResponseBodyAsString().trim(); |
|
|
|
|
|
post.releaseConnection(); |
|
|
|
|
|
myLogger.debug("Postback time (msec): " + postingTime); |
|
|
|
|
|
CommonLogger.activity.info("Received response: " + (responseBody.length() == 0? "[empty]" : responseBody)); |
|
|
|
|
|
if (responseBody.trim().length() == 0) return PostBackStatus.SUCCESS; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
catch (ConnectTimeoutException e) |
|
|
|
|
|
{ |
|
|
|
|
|
CommonLogger.alarm.warn("IO problem while posting to \"" + url + "\": " + xml + " -- " + e.getMessage()); |
|
|
|
|
|
return PostBackStatus.SERVER_IO_ERROR; |
|
|
|
|
|
} |
|
|
|
|
|
catch (IOException e) |
|
|
|
|
|
{ |
|
|
|
|
|
CommonLogger.alarm.warn("IO problem while posting to \"" + url + "\": " + xml + " -- " + e.getMessage()); |
|
|
|
|
|
return PostBackStatus.SERVER_IO_ERROR; |
|
|
|
|
|
} |
|
|
|
|
|
catch (IllegalArgumentException e) |
|
|
|
|
|
{ |
|
|
|
|
|
CommonLogger.alarm.warn("When posting to \"" + url + "\": " + e.getMessage()); |
|
|
|
|
|
return PostBackStatus.IRRECOVERABLE_ERROR; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
CommonLogger.alarm.error("While posting back to broadcast requester: " + e); |
|
|
|
|
|
return PostBackStatus.IRRECOVERABLE_ERROR; |
|
|
} |
|
|
} |
|
|
if (responseBody == null) |
|
|
|
|
|
|
|
|
catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) |
|
|
{ |
|
|
{ |
|
|
CommonLogger.alarm.warn("When posting to \"" + url + "\": " + " Exhausted allowable redirects"); |
|
|
|
|
|
|
|
|
CommonLogger.alarm.error("Totally unexpected. While constructing HttpClient for posting back to broadcast requester: " + e); |
|
|
return PostBackStatus.IRRECOVERABLE_ERROR; |
|
|
return PostBackStatus.IRRECOVERABLE_ERROR; |
|
|
} |
|
|
} |
|
|
// parse into xml doc |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String xmlStr; |
|
|
|
|
|
try |
|
|
|
|
|
{ |
|
|
|
|
|
xmlBytes = EntityUtils.toByteArray(response.getEntity()); |
|
|
|
|
|
xmlStr = new String(xmlBytes); |
|
|
|
|
|
myLogger.debug("Received resposne: " + xmlStr); |
|
|
|
|
|
} |
|
|
|
|
|
catch (IOException e) |
|
|
|
|
|
{ |
|
|
|
|
|
CommonLogger.alarm.error("While getting response from posting to broadcast requester: " + e); |
|
|
|
|
|
return PostBackStatus.SERVER_IO_ERROR; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
Document xmlDoc = null; |
|
|
Document xmlDoc = null; |
|
|
try |
|
|
try |
|
|
{ |
|
|
{ |
|
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
|
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
|
|
DocumentBuilder builder = factory.newDocumentBuilder(); |
|
|
DocumentBuilder builder = factory.newDocumentBuilder(); |
|
|
xmlDoc = builder.parse(new ByteArrayInputStream(responseBody.getBytes())); |
|
|
|
|
|
|
|
|
xmlDoc = builder.parse(new ByteArrayInputStream(xmlBytes)); |
|
|
} |
|
|
} |
|
|
catch (Exception e) |
|
|
catch (Exception e) |
|
|
{ |
|
|
{ |
|
|
CommonLogger.alarm.warn("xml parse problem on received response from " + postBackURL + ": " + responseBody); |
|
|
|
|
|
|
|
|
CommonLogger.alarm.warn("xml parse problem on received response from " + postBackURL + ": " + xmlStr); |
|
|
return PostBackStatus.IRRECOVERABLE_ERROR; |
|
|
return PostBackStatus.IRRECOVERABLE_ERROR; |
|
|
} |
|
|
} |
|
|
if (!xmlDoc.getDocumentElement().getNodeName().startsWith(xmlTopElement)) |
|
|
if (!xmlDoc.getDocumentElement().getNodeName().startsWith(xmlTopElement)) |
|
|
{ |
|
|
{ |
|
|
CommonLogger.alarm.warn("xml response from " + postBackURL + " not a <" + xmlTopElement + "> response: " + responseBody); |
|
|
|
|
|
|
|
|
CommonLogger.alarm.warn("xml response from " + postBackURL + " not a <" + xmlTopElement + "> response: " + xmlStr); |
|
|
return PostBackStatus.IRRECOVERABLE_ERROR; |
|
|
return PostBackStatus.IRRECOVERABLE_ERROR; |
|
|
} |
|
|
} |
|
|
XPath xpathEngine = XPathFactory.newInstance().newXPath(); |
|
|
XPath xpathEngine = XPathFactory.newInstance().newXPath(); |
|
|
@@ -419,42 +390,6 @@ public class PostBack |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* Queues reports to postQueue only if the queue size has not reached the |
|
|
|
|
|
* maxQueueSize. |
|
|
|
|
|
* @param reports to be added back to postQueue |
|
|
|
|
|
* @return true if all jobs have been added to queue, false otherwise (queue full) |
|
|
|
|
|
*/ |
|
|
|
|
|
/* |
|
|
|
|
|
@Deprecated |
|
|
|
|
|
public boolean queueReports(List<String> reports) |
|
|
|
|
|
{ |
|
|
|
|
|
myLogger.debug(myName + ": postQueue size: " + postQueue.size()); |
|
|
|
|
|
synchronized(postQueue) |
|
|
|
|
|
{ |
|
|
|
|
|
Iterator<String> iter = reports.iterator(); |
|
|
|
|
|
int count = 0; // Number of reports added back to postQueue |
|
|
|
|
|
while (iter.hasNext()) |
|
|
|
|
|
{ |
|
|
|
|
|
String report = iter.next(); |
|
|
|
|
|
if (postQueue.size() < maxQueueSize) |
|
|
|
|
|
{ |
|
|
|
|
|
postQueue.add(report); |
|
|
|
|
|
count++; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (count > 0) postQueue.notify(); |
|
|
|
|
|
boolean returnValue = (count == reports.size()); |
|
|
|
|
|
if (!returnValue) |
|
|
|
|
|
{ |
|
|
|
|
|
CommonLogger.alarm.warn(myName |
|
|
|
|
|
+ ".queueReport method returning false, having queued " |
|
|
|
|
|
+ count + " out of " + reports.size()); |
|
|
|
|
|
} |
|
|
|
|
|
return returnValue; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
public void terminate() |
|
|
public void terminate() |
|
|
{ |
|
|
{ |
|
|
|