| @@ -3,11 +3,16 @@ package altk.comm.engine.postback; | |||
| import java.io.ByteArrayInputStream; | |||
| import java.io.IOException; | |||
| 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.LinkedList; | |||
| import java.util.List; | |||
| import java.util.Queue; | |||
| import javax.net.ssl.SSLContext; | |||
| import javax.xml.parsers.DocumentBuilder; | |||
| import javax.xml.parsers.DocumentBuilderFactory; | |||
| import javax.xml.xpath.XPath; | |||
| @@ -15,14 +20,18 @@ import javax.xml.xpath.XPathConstants; | |||
| import javax.xml.xpath.XPathExpressionException; | |||
| 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.w3c.dom.Document; | |||
| import org.w3c.dom.Node; | |||
| @@ -183,110 +192,72 @@ public class PostBack | |||
| } | |||
| 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 | |||
| { | |||
| 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) | |||
| { | |||
| CommonLogger.alarm.warn("While adding this application/xml content to PostBack: " + xml + " -- " + e); | |||
| 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; | |||
| } | |||
| // 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; | |||
| try | |||
| { | |||
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | |||
| DocumentBuilder builder = factory.newDocumentBuilder(); | |||
| xmlDoc = builder.parse(new ByteArrayInputStream(responseBody.getBytes())); | |||
| xmlDoc = builder.parse(new ByteArrayInputStream(xmlBytes)); | |||
| } | |||
| 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; | |||
| } | |||
| 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; | |||
| } | |||
| XPath xpathEngine = XPathFactory.newInstance().newXPath(); | |||
| @@ -419,42 +390,6 @@ public class PostBack | |||
| 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() | |||
| { | |||