下面列出了怎么用org.apache.http.NoHttpResponseException的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void testHttpPlainFail() throws Exception {
thrown.expect(NoHttpResponseException.class);
enableHTTPClientSSL = false;
trustHTTPServerCertificate = true;
sendHTTPClientCertificate = false;
final Settings settings = Settings.builder().put("opendistro_security.ssl.transport.enabled", false)
.put(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_HTTP_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL)
.put(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_TRANSPORT_ENABLE_OPENSSL_IF_AVAILABLE, allowOpenSSL)
.put(SSLConfigConstants.OPENDISTRO_SECURITY_SSL_HTTP_KEYSTORE_ALIAS, "node-0").put("opendistro_security.ssl.http.enabled", true)
.put("opendistro_security.ssl.http.clientauth_mode", "OPTIONAL")
.put("opendistro_security.ssl.http.keystore_filepath", getAbsoluteFilePathFromClassPath("node-0-keystore.jks"))
.put("opendistro_security.ssl.http.truststore_filepath", getAbsoluteFilePathFromClassPath("truststore.jks")).build();
startES(settings);
Assert.assertTrue(executeSimpleRequest("_opendistro/_security/sslinfo?pretty").length() > 0);
Assert.assertTrue(executeSimpleRequest("_nodes/settings?pretty").contains(clustername));
Assert.assertTrue(executeSimpleRequest("_opendistro/_security/sslinfo?pretty").contains("CN=node-0.example.com,OU=SSL,O=Test,L=Test,C=DE"));
}
private HttpEngine() {
this.mDefaultHttpClient = null;
this.mDefaultHttpClient = createHttpClient();
this.mDefaultHttpClient.setHttpRequestRetryHandler(new HttpRequestRetryHandler() {
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if (DataStatistics.getInstance().isDebug()) {
Log.d(DataStatistics.TAG, exception.getClass() + NetworkUtils.DELIMITER_COLON + exception.getMessage() + ",executionCount:" + executionCount);
}
if (executionCount >= 3) {
return false;
}
if (exception instanceof NoHttpResponseException) {
return true;
}
if (exception instanceof ClientProtocolException) {
return true;
}
return false;
}
});
}
@Override
public boolean neadRetry(Exception exception, BulkCommand bulkCommand) {
if (exception instanceof HttpHostConnectException //NoHttpResponseException 重试
|| exception instanceof ConnectTimeoutException //连接超时重试
|| exception instanceof UnknownHostException
|| exception instanceof NoHttpResponseException
|| exception instanceof NoServerElasticSearchException
// || exception instanceof SocketTimeoutException //响应超时不重试,避免造成业务数据不一致
) {
return true;
}
if(exception instanceof SocketException){
String message = exception.getMessage();
if(message != null && message.trim().equals("Connection reset")) {
return true;
}
}
return false;
}
protected void sendCommitWithRetry(Replica replica) throws Exception {
String replicaCoreUrl = replica.getCoreUrl();
log.info("Sending commit request to: {}", replicaCoreUrl);
final RTimer timer = new RTimer();
try (HttpSolrClient client = getHttpSolrClient(replicaCoreUrl)) {
try {
client.commit();
if (log.isInfoEnabled()) {
log.info("Sent commit request to {} OK, took {}ms", replicaCoreUrl, timer.getTime());
}
} catch (Exception exc) {
Throwable rootCause = SolrException.getRootCause(exc);
if (rootCause instanceof NoHttpResponseException) {
log.warn("No HTTP response from sending commit request to {}; will re-try after waiting 3 seconds", replicaCoreUrl);
Thread.sleep(3000);
client.commit();
log.info("Second attempt at sending commit to {} succeeded", replicaCoreUrl);
} else {
throw exc;
}
}
}
}
public boolean retryRequest(IOException exception, int executionCount,
HttpContext context) {
// 设置恢复策略,在发生异常时候将自动重试3次
if (executionCount >= 3) {
// 如果连接次数超过了最大值则停止重试
return false;
}
if (exception instanceof NoHttpResponseException) {
// 如果服务器连接失败重试
return true;
}
if (exception instanceof SSLHandshakeException) {
// 不要重试ssl连接异常
return false;
}
HttpRequest request = (HttpRequest) context
.getAttribute(ExecutionContext.HTTP_REQUEST);
boolean idempotent = (request instanceof HttpEntityEnclosingRequest);
if (!idempotent) {
// 重试,如果请求是考虑幂等
return true;
}
return false;
}
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Decide about retry #" + executionCount + " for exception " + exception.getMessage());
}
if (executionCount >= _maxRetryCount) {
// Do not retry if over max retry count
return false;
} else if (exception instanceof NoHttpResponseException) {
// Retry if the server dropped connection on us
return true;
} else if (exception instanceof SSLHandshakeException) {
// Do not retry on SSL handshake exception
return false;
}
HttpRequest request = (HttpRequest) context.getAttribute(HttpCoreContext.HTTP_REQUEST);
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
// Retry if the request is considered idempotent
return idempotent;
}
private void validateResponse(HttpResponse response) throws IOException {
StatusLine status = response.getStatusLine();
if (status.getStatusCode() >= 400) {
String messagePrefix = String.format("The server returned status code %d. Possible reasons include:", status.getStatusCode());
List<String> reasons = Arrays.asList(
"This agent has been deleted from the configuration",
"This agent is pending approval",
"There is possibly a reverse proxy (or load balancer) that has been misconfigured. See "
+ docsUrl("/installation/configure-reverse-proxy.html#agents-and-reverse-proxies") +
" for details."
);
String delimiter = "\n - ";
throw new ClientProtocolException(messagePrefix + delimiter + String.join(delimiter, reasons));
}
if (status.getStatusCode() >= 300) {
throw new NoHttpResponseException("Did not receive successful HTTP response: status code = " + status.getStatusCode() + ", status message = [" + status.getReasonPhrase() + "]");
}
}
private String sendQ(String query, int timeout)
throws ClientProtocolException, IOException, NoHttpResponseException {
logger.trace("Send query (timeout={}): {}", timeout, query);
postReq.setEntity(new StringEntity(query, "UTF-8"));
postReq.addHeader("content-type", "text/xml");
final RequestConfig params = RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(timeout)
.build();
postReq.setConfig(params);
// Execute POST
HttpResponse response = client.execute(postReq, IhcConnectionPool.getInstance().getHttpContext());
String resp = EntityUtils.toString(response.getEntity());
logger.trace("Received response: {}", resp);
return resp;
}
@Test
public void testSSLPlainText() throws Exception {
//if this fails permanently look in the logs for an abstract method error or method not found error.
//needs proper ssl plugin version
Settings additionalSettings = Settings.builder()
.put("opendistro_security.ssl.http.enabled",true)
.put("opendistro_security.ssl.http.keystore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/node-0-keystore.jks"))
.put("opendistro_security.ssl.http.truststore_filepath", FileHelper.getAbsoluteFilePathFromClassPath("auditlog/truststore.jks"))
.put("opendistro_security.audit.type", TestAuditlogImpl.class.getName())
.put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_TRANSPORT_CATEGORIES, "NONE")
.put(ConfigConstants.OPENDISTRO_SECURITY_AUDIT_CONFIG_DISABLED_REST_CATEGORIES, "NONE")
.put("opendistro_security.audit.threadpool.size", 0)
.build();
setup(additionalSettings);
TestAuditlogImpl.clear();
try {
nonSslRestHelper().executeGetRequest("_search", encodeBasicHeader("admin", "admin"));
Assert.fail();
} catch (NoHttpResponseException e) {
//expected
}
Thread.sleep(1500);
System.out.println(TestAuditlogImpl.sb.toString());
Assert.assertFalse(TestAuditlogImpl.messages.isEmpty());
Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("SSL_EXCEPTION"));
Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("exception_stacktrace"));
Assert.assertTrue(TestAuditlogImpl.sb.toString().contains("not an SSL/TLS record"));
Assert.assertTrue(validateMsgs(TestAuditlogImpl.messages));
}
/**
* Validate the given response as contained in the HttpPost object,
* throwing an exception if it does not correspond to a successful HTTP response.
* <p>Default implementation rejects any HTTP status code beyond 2xx, to avoid
* parsing the response body and trying to deserialize from a corrupted stream.
* @param config the HTTP invoker configuration that specifies the target service
* @param response the resulting HttpResponse to validate
* @throws java.io.IOException if validation failed
*/
protected void validateResponse(HttpInvokerClientConfiguration config, HttpResponse response)
throws IOException {
StatusLine status = response.getStatusLine();
if (status.getStatusCode() >= 300) {
throw new NoHttpResponseException(
"Did not receive successful HTTP response: status code = " + status.getStatusCode() +
", status message = [" + status.getReasonPhrase() + "]");
}
}
/**
* Validate the given response as contained in the HttpPost object,
* throwing an exception if it does not correspond to a successful HTTP response.
* <p>Default implementation rejects any HTTP status code beyond 2xx, to avoid
* parsing the response body and trying to deserialize from a corrupted stream.
* @param config the HTTP invoker configuration that specifies the target service
* @param response the resulting HttpResponse to validate
* @throws java.io.IOException if validation failed
*/
protected void validateResponse(HttpInvokerClientConfiguration config, HttpResponse response)
throws IOException {
StatusLine status = response.getStatusLine();
if (status.getStatusCode() >= 300) {
throw new NoHttpResponseException(
"Did not receive successful HTTP response: status code = " + status.getStatusCode() +
", status message = [" + status.getReasonPhrase() + "]");
}
}
/**
* Validate the given response as contained in the HttpPost object,
* throwing an exception if it does not correspond to a successful HTTP response.
* <p>Default implementation rejects any HTTP status code beyond 2xx, to avoid
* parsing the response body and trying to deserialize from a corrupted stream.
* @param config the HTTP invoker configuration that specifies the target service
* @param response the resulting HttpResponse to validate
* @throws java.io.IOException if validation failed
*/
protected void validateResponse(HttpInvokerClientConfiguration config, HttpResponse response)
throws IOException {
StatusLine status = response.getStatusLine();
if (status.getStatusCode() >= 300) {
throw new NoHttpResponseException(
"Did not receive successful HTTP response: status code = " + status.getStatusCode() +
", status message = [" + status.getReasonPhrase() + "]");
}
}
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if (executionCount >= 3) {// 如果已经重试了3次,就放弃
return false;
}
if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
return true;
}
if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
return false;
}
if (exception instanceof InterruptedIOException) {// 超时
return true;
}
if (exception instanceof UnknownHostException) {// 目标服务器不可达
return false;
}
if (exception instanceof ConnectTimeoutException) {// 连接被拒绝
return false;
}
if (exception instanceof SSLException) {// ssl握手异常
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
// 如果请求是幂等的,就再次尝试
return !(request instanceof HttpEntityEnclosingRequest);
}
protected BackgroundException wrap(final T failure, final String title, final StringBuilder buffer) {
if(buffer.toString().isEmpty()) {
log.warn(String.format("No message for failure %s", failure));
this.append(buffer, LocaleFactory.localizedString("Unknown"));
}
for(Throwable cause : ExceptionUtils.getThrowableList(failure)) {
if(cause instanceof InterruptedIOException) {
// Handling socket timeouts
return new ConnectionTimeoutException(buffer.toString(), failure);
}
if(cause instanceof TimeoutException) {
//
return new ConnectionTimeoutException(buffer.toString(), failure);
}
if(cause instanceof SocketException) {
return new DefaultSocketExceptionMappingService().map((SocketException) cause);
}
if(cause instanceof EOFException) {
return new ConnectionRefusedException(buffer.toString(), failure);
}
if(cause instanceof UnknownHostException) {
return new ResolveFailedException(buffer.toString(), failure);
}
if(cause instanceof NoHttpResponseException) {
return new ConnectionRefusedException(buffer.toString(), failure);
}
if(cause instanceof ConnectionClosedException) {
return new ConnectionRefusedException(buffer.toString(), failure);
}
if(cause instanceof InterruptedException) {
return new ConnectionCanceledException(buffer.toString(), failure);
}
}
if(failure instanceof RuntimeException) {
return new ConnectionCanceledException(title, buffer.toString(), failure);
}
return new BackgroundException(title, buffer.toString(), failure);
}
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if (executionCount >= 3) {// 如果已经重试了3次,就放弃
return false;
}
if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
return true;
}
if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
return false;
}
if (exception instanceof InterruptedIOException) {// 超时
return true;
}
if (exception instanceof UnknownHostException) {// 目标服务器不可达
return false;
}
if (exception instanceof ConnectTimeoutException) {// 连接被拒绝
return false;
}
if (exception instanceof SSLException) {// ssl握手异常
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
// 如果请求是幂等的,就再次尝试
if (!(request instanceof HttpEntityEnclosingRequest)) {
return true;
}
return false;
}
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if (executionCount >= 5) {// 如果已经重试了5次,就放弃
return false;
}
if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
return true;
}
if (exception instanceof InterruptedIOException) {// 超时
return false;
}
if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
return false;
}
if (exception instanceof UnknownHostException) {// 目标服务器不可达
return false;
}
if (exception instanceof ConnectTimeoutException) {// 连接被拒绝
return false;
}
if (exception instanceof SSLException) {// SSL握手异常
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
// 如果请求是幂等的,就再次尝试
if (!(request instanceof HttpEntityEnclosingRequest)) {
return true;
}
return false;
}
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if (executionCount >= 3) {// 如果已经重试了3次,就放弃
return false;
}
if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
return true;
}
if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
return false;
}
if (exception instanceof InterruptedIOException) {// 超时
return true;
}
if (exception instanceof UnknownHostException) {// 目标服务器不可达
return false;
}
if (exception instanceof ConnectTimeoutException) {// 连接被拒绝
return false;
}
if (exception instanceof SSLException) {// ssl握手异常
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
// 如果请求是幂等的,就再次尝试
if (!(request instanceof HttpEntityEnclosingRequest)) {
return true;
}
return false;
}
@Test
public void shouldHaveNoResponseFromUnprefixedRequest() {
try {
final ResponseEntity<String> response = this.restTemplate.getForEntity(
"http://localhost:" + port + "/hello",
String.class
);
fail("shouldn't have had a response");
} catch (final ResourceAccessException e) {
assertThat(e).hasCauseInstanceOf(NoHttpResponseException.class);
}
}
@Test public void testRetryOnMissingHttpResponse() throws Exception {
final byte[] requestBytes = "fake_request".getBytes(UTF_8);
final CloseableHttpResponse badResponse = mock(CloseableHttpResponse.class);
final CloseableHttpResponse goodResponse = mock(CloseableHttpResponse.class);
final StatusLine badStatusLine = mock(StatusLine.class);
final StatusLine goodStatusLine = mock(StatusLine.class);
final StringEntity responseEntity = new StringEntity("success");
final Answer<CloseableHttpResponse> failThenSucceed = new Answer<CloseableHttpResponse>() {
private int iteration = 0;
@Override public CloseableHttpResponse answer(InvocationOnMock invocation) throws Throwable {
iteration++;
if (1 == iteration) {
throw new NoHttpResponseException("The server didn't respond!");
} else {
return goodResponse;
}
}
};
final AvaticaCommonsHttpClientImpl client = mock(AvaticaCommonsHttpClientImpl.class);
when(client.send(any(byte[].class))).thenCallRealMethod();
when(client.execute(any(HttpPost.class), any(HttpClientContext.class))).then(failThenSucceed);
when(badResponse.getStatusLine()).thenReturn(badStatusLine);
when(badStatusLine.getStatusCode()).thenReturn(HttpURLConnection.HTTP_UNAVAILABLE);
when(goodResponse.getStatusLine()).thenReturn(goodStatusLine);
when(goodStatusLine.getStatusCode()).thenReturn(HttpURLConnection.HTTP_OK);
when(goodResponse.getEntity()).thenReturn(responseEntity);
byte[] responseBytes = client.send(requestBytes);
assertEquals("success", new String(responseBytes, UTF_8));
}
/**
* Validate the given response as contained in the HttpPost object,
* throwing an exception if it does not correspond to a successful HTTP response.
* <p>Default implementation rejects any HTTP status code beyond 2xx, to avoid
* parsing the response body and trying to deserialize from a corrupted stream.
* @param config the HTTP invoker configuration that specifies the target service
* @param response the resulting HttpResponse to validate
* @throws java.io.IOException if validation failed
*/
protected void validateResponse(HttpInvokerClientConfiguration config, HttpResponse response)
throws IOException {
StatusLine status = response.getStatusLine();
if (status.getStatusCode() >= 300) {
throw new NoHttpResponseException(
"Did not receive successful HTTP response: status code = " + status.getStatusCode() +
", status message = [" + status.getReasonPhrase() + "]");
}
}
private void verifyConnectionClosedException(Throwable ex) {
boolean isNoHttpResponseEx = (ex instanceof NoHttpResponseException);
boolean isSocketExForConnectionReset =
(ex instanceof SocketException) && (ex.getMessage().equals("Connection reset"));
assertThat(isNoHttpResponseEx || isSocketExForConnectionReset)
.withFailMessage("Expected a NoHttpResponseException, or a SocketException with message "
+ "'Connection reset', but instead found: " + ex.toString()
)
.isTrue();
}
/**
* Determine if a request to Solr failed due to a communication error,
* which is generally retry-able.
*/
public static boolean checkCommunicationError(Exception exc) {
Throwable rootCause = SolrException.getRootCause(exc);
boolean wasCommError =
(rootCause instanceof ConnectException ||
rootCause instanceof ConnectTimeoutException ||
rootCause instanceof NoHttpResponseException ||
rootCause instanceof SocketException);
return wasCommError;
}
@Test
public void emptyResponse() throws Exception {
wiremock.stubFor(get(urlEqualTo("/resource"))
.willReturn(aResponse().withFault(Fault.EMPTY_RESPONSE)));
assertThatThrownBy(() -> this.service.go()).hasCauseInstanceOf(NoHttpResponseException.class);
}
@Test
public void emptyResponse() throws Exception {
wiremock.stubFor(get(urlEqualTo("/resource"))
.willReturn(aResponse().withFault(Fault.EMPTY_RESPONSE)));
assertThatThrownBy(() -> this.service.go()).hasCauseInstanceOf(NoHttpResponseException.class);
}
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
boolean retry = super.retryRequest(exception, executionCount, context);
if (!retry && exception instanceof NoHttpResponseException && executionCount < 5) {
return true;
} else {
return retry;
}
}
static boolean isKnownConnectionException(Throwable t) {
for (; t != null; t = t.getCause()) {
if (t instanceof SocketException ||
t instanceof SocketTimeoutException ||
t instanceof NoHttpResponseException ||
t instanceof EOFException)
return true;
}
return false;
}
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
if (executionCount >= 5) {// 如果已经重试了5次,就放弃
return false;
}
if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
return true;
}
if (exception instanceof InterruptedIOException) {// 超时
return false;
}
if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
return false;
}
if (exception instanceof UnknownHostException) {// 目标服务器不可达
return false;
}
if (exception instanceof ConnectTimeoutException) {// 连接被拒绝
return false;
}
if (exception instanceof SSLException) {// SSL握手异常
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
// 如果请求是幂等的,就再次尝试
if (!(request instanceof HttpEntityEnclosingRequest)) {
return true;
}
return false;
}
private void setPassword(String rootUrl) throws IOException, ClientProtocolException {
HttpClient client = createClient("neo4j");
RetryPolicy retryPolicy =
new RetryPolicy()
.retryOn(NoHttpResponseException.class)
.withDelay(1, TimeUnit.SECONDS)
.withMaxRetries(3);
Failsafe.with(retryPolicy).run(() -> callSetPassword(rootUrl, client));
}
@Test( expected = NoHttpResponseException.class )
// This test exists for demonstration purpose only, it do not test usefull things but it's on purpose
public void testNoSSL()
throws IOException
{
HttpGet get = new HttpGet( "http://127.0.0.1:" + httpsPort + "/hello" );
defaultHttpClient.execute( get );
fail( "We could reach the HTTPS connector using a HTTP url, that's no good" );
}
@Test
public void shouldBreakOnInvalidAuthenticationHandler() throws Exception {
final CombinedTestClient client = new CombinedTestClient(getProtocol());
try {
client.sendAndAssert("2+2", 4);
Assert.fail("An exception should be thrown with an invalid authentication handler");
} catch (NoHttpResponseException | SocketException e) {
} finally {
client.close();
}
}