| @@ -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() | ||||
| { | { | ||||