Author: cwiklik Date: Thu Dec 13 16:32:14 2018 New Revision: 1848866 URL: http://svn.apache.org/viewvc?rev=1848866&view=rev Log: UIMA-5933 Simplified error handling caught when calling HttpClient.execute(). Added new JUnit tests to test 3 new scenarios: 1) IOException 2) NoRouteToHostException 3) URILSyntaxException
Modified: uima/uima-ducc/trunk/uima-ducc-pullservice/src/main/java/org/apache/uima/ducc/ps/service/transport/http/HttpServiceTransport.java uima/uima-ducc/trunk/uima-ducc-pullservice/src/test/java/org/apache/uima/ducc/ps/transport/JunitTransportTestCase.java Modified: uima/uima-ducc/trunk/uima-ducc-pullservice/src/main/java/org/apache/uima/ducc/ps/service/transport/http/HttpServiceTransport.java URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-pullservice/src/main/java/org/apache/uima/ducc/ps/service/transport/http/HttpServiceTransport.java?rev=1848866&r1=1848865&r2=1848866&view=diff ============================================================================== --- uima/uima-ducc/trunk/uima-ducc-pullservice/src/main/java/org/apache/uima/ducc/ps/service/transport/http/HttpServiceTransport.java (original) +++ uima/uima-ducc/trunk/uima-ducc-pullservice/src/main/java/org/apache/uima/ducc/ps/service/transport/http/HttpServiceTransport.java Thu Dec 13 16:32:14 2018 @@ -20,7 +20,9 @@ package org.apache.uima.ducc.ps.service. import java.io.IOException; import java.lang.management.ManagementFactory; +import java.net.ConnectException; import java.net.InetAddress; +import java.net.NoRouteToHostException; import java.net.SocketException; import java.net.URI; import java.net.URISyntaxException; @@ -29,6 +31,7 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; +import org.apache.commons.httpclient.URIException; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; @@ -241,7 +244,7 @@ public class HttpServiceTransport implem return response; } - private String doPost(HttpPost postMethod) throws URISyntaxException, NoHttpResponseException, IOException, TransportException { + private String doPost(HttpPost postMethod) throws URISyntaxException, IOException, TransportException { postMethod.setURI(new URI(currentTargetUrl.asString())); HttpResponse response = httpClient.execute(postMethod); @@ -251,12 +254,10 @@ public class HttpServiceTransport implem HttpEntity entity = response.getEntity(); String serializedResponse = EntityUtils.toString(entity); StatusLine statusLine = response.getStatusLine(); - if (statusLine.getStatusCode() != 200 && logger.isLoggable(Level.WARNING) ) { - - logger.log(Level.WARNING,"execute", "Unable to Communicate with client - Error:"+statusLine); - logger.log(Level.WARNING, "Content causing error:"+serializedResponse); - throw new TransportException( - "Http Client Unable to Communicate with a remote client - Error:" + statusLine); + if (statusLine.getStatusCode() != 200 ) { + // all IOExceptions are retried + throw new IOException( + "Unexpected HttpClient response status:"+statusLine+ " Content causing error:"+serializedResponse); } stats.incrementSuccessCount(); @@ -277,61 +278,45 @@ public class HttpServiceTransport implem postMethod.setEntity(e); String serializedResponse = null; try { - serializedResponse = doPost(postMethod); + String simulatedException; + // To test transport errors add command line option -DMockHttpPostError=exception where + // exception is one of the following Strings: + // + // IOException, + // SocketException, + // UnknownHostException, + // NoRouteToHostException, + // NoHttpResponseException, + // HttpHostConnectException, + // URISyntaxException - } catch ( NoHttpResponseException ex ) { - if ( stopping ) { - System.out.println("Process Thread:"+Thread.currentThread().getId()+" NoHttpResponseException "); - throw new TransportException(ex); + if ( ( simulatedException = System.getProperty("MockHttpPostError")) != null ) { + HttpClientExceptionGenerator mockExceptionGenerator = + new HttpClientExceptionGenerator(simulatedException); + mockExceptionGenerator.throwSimulatedException(); } else { - serializedResponse = retryUntilSuccessfull(serializedRequest, postMethod); + serializedResponse = doPost(postMethod); } - - } catch (HttpHostConnectException | UnknownHostException ex ) { + } catch( IOException | URISyntaxException ex) { if ( stopping ) { - System.out.println(this.getClass().getName()+".dispatch() Process Thread:"+Thread.currentThread().getId()+" HttpHostConnectException "); - + // looks like the process is in the shutdown mode. Log an exception and dont retry + logger.log(Level.INFO,"Process Thread:"+Thread.currentThread().getId()+" - Process is already stopping - Caught Exception while calling doPost() \n"+ex); throw new TransportException(ex); + } else { + if ( log ) { + log = false; + stats.incrementErrorCount(); + logger.log(Level.WARNING, this.getClass().getName()+".dispatch() >>>>>>>>>> Handling Exception \n"+ex); +// System.out.println( this.getClass().getName()+".dispatch() >>>>>>>>>> Unable to communicate with target:"+currentTargetUrl.asString()+" - retrying until successfull - with "+threadSleepTime/1000+" seconds wait between retries "); + logger.log(Level.INFO, ">>>>>>>>>> Unable to communicate with target:"+currentTargetUrl.asString()+" - retrying until successfull - with "+threadSleepTime/1000+" seconds wait between retries "); + } + serializedResponse = retryUntilSuccessfull(serializedRequest, postMethod); + log = true; + logger.log(Level.INFO, "Established connection to target:"+currentTargetUrl.asString()); } - stats.incrementErrorCount(); - Action action = handleConnectionError(ex); - if ( Action.CONTINUE.equals(action)) { - try { - // Lost connection to the Task Allocation App - // Block until connection is restored - if ( log ) { - log = false; - System.out.println( this.getClass().getName()+".dispatch() >>>>>>>>>> Unable to connect to target:"+currentTargetUrl.asString()+" - retrying until successfull - with "+threadSleepTime/1000+" seconds wait between retries "); - logger.log(Level.INFO, ">>>>>>>>>> Unable to connect to target:"+currentTargetUrl.asString()+" - retrying until successfull - with "+threadSleepTime/1000+" seconds wait between retries "); - } - serializedResponse = retryUntilSuccessfull(serializedRequest, postMethod); - log = true; - logger.log(Level.INFO, "Established connection to target:"+currentTargetUrl.asString()); - - } catch( Exception ee) { - log = true; - // Fail here - bad URI - } - - - } else if ( Action.TERMINATE.equals(action)) { - ex.printStackTrace(); - } - - } catch (SocketException ex) { - if ( stopping ) { - throw new TransportException(ex); - } - - } catch (TransportException ex) { - - } catch (Exception ex) { - ex.printStackTrace(); - throw new TransportException(ex); - } - finally { + } finally { postMethod.releaseConnection(); } return serializedResponse; @@ -371,6 +356,53 @@ public class HttpServiceTransport implem } - + public static class HttpClientExceptionGenerator { + public enum ERROR{ IOException, SocketException, UnknownHostException, NoRouteToHostException,NoHttpResponseException, HttpHostConnectException, URISyntaxException}; + + Exception exceptionClass; + + public HttpClientExceptionGenerator(String exc) { + for( ERROR e : ERROR.values()) { + if ( exc != null && e.name().equals(exc)) { + switch(e) { + case IOException: + exceptionClass = new IOException("Simulated IOException"); + break; + case URISyntaxException: + exceptionClass = new URISyntaxException("", "Simulated URISyntaxException"); + break; + case NoRouteToHostException: + exceptionClass = new NoRouteToHostException("Simulated NoRouteToHostException"); + break; + case NoHttpResponseException: + exceptionClass = new NoHttpResponseException("Simulated NoHttpResponseException"); + break; + case SocketException: + exceptionClass = new SocketException("Simulated SocketException"); + break; + case UnknownHostException: + exceptionClass = new UnknownHostException("Simulated UnknownHostException"); + break; + + default: + + + } + } + } + } + public void throwSimulatedException() throws IOException, URISyntaxException { + if ( exceptionClass != null ) { + if ( exceptionClass instanceof IOException ) { + throw (IOException)exceptionClass; + } else if ( exceptionClass instanceof URISyntaxException ) { + throw (URISyntaxException)exceptionClass; + } + + } + } + + + } } Modified: uima/uima-ducc/trunk/uima-ducc-pullservice/src/test/java/org/apache/uima/ducc/ps/transport/JunitTransportTestCase.java URL: http://svn.apache.org/viewvc/uima/uima-ducc/trunk/uima-ducc-pullservice/src/test/java/org/apache/uima/ducc/ps/transport/JunitTransportTestCase.java?rev=1848866&r1=1848865&r2=1848866&view=diff ============================================================================== --- uima/uima-ducc/trunk/uima-ducc-pullservice/src/test/java/org/apache/uima/ducc/ps/transport/JunitTransportTestCase.java (original) +++ uima/uima-ducc/trunk/uima-ducc-pullservice/src/test/java/org/apache/uima/ducc/ps/transport/JunitTransportTestCase.java Thu Dec 13 16:32:14 2018 @@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletRes import org.apache.uima.ducc.ps.service.registry.DefaultRegistryClient; import org.apache.uima.ducc.ps.service.transport.ITargetURI; import org.apache.uima.ducc.ps.service.transport.http.HttpServiceTransport; +import org.apache.uima.ducc.ps.service.transport.http.HttpServiceTransport.HttpClientExceptionGenerator.ERROR; import org.apache.uima.ducc.ps.service.transport.target.HttpTargetURI; import org.eclipse.jetty.server.Connector; import org.eclipse.jetty.server.Server; @@ -91,7 +92,14 @@ public class JunitTransportTestCase { } System.out.println("Jetty Stopped"); } - + private void wait(DefaultRegistryClient registryClient) { + synchronized(registryClient) { + try { + registryClient.wait(5*1000); + + } catch( InterruptedException e) {} + } + } @Test public void testTransportBasicConnectivity() throws Exception { @@ -106,6 +114,51 @@ public class JunitTransportTestCase { // assertThat("Response Code", http.getResponseCode(), (equal((HttpStatus.OK_200))); } + @Test + public void testTransportIOException() throws Exception + { + System.out.println(".... Test::testTransportIOException"); + int scaleout = 12; + ITargetURI targetUrl = new HttpTargetURI("http://localhost:"+httpPort+"/"+app); + DefaultRegistryClient registryClient = + new DefaultRegistryClient(targetUrl); + HttpServiceTransport transport = new HttpServiceTransport(registryClient, scaleout); + transport.initialize(); + System.setProperty("MockHttpPostError", ERROR.IOException.name()); + transport.dispatch("Dummy Message"); + + wait(registryClient); + } + @Test + public void testTransportNoRoutToHostException() throws Exception + { + System.out.println(".... Test::testTransportNoRoutToHostException"); + int scaleout = 12; + ITargetURI targetUrl = new HttpTargetURI("http://localhost:"+httpPort+"/"+app); + DefaultRegistryClient registryClient = + new DefaultRegistryClient(targetUrl); + HttpServiceTransport transport = new HttpServiceTransport(registryClient, scaleout); + transport.initialize(); + System.setProperty("MockHttpPostError", ERROR.NoRouteToHostException.name()); + transport.dispatch("Dummy Message"); + wait(registryClient); + + } + @Test + public void testTransportURISyntaxException() throws Exception + { + System.out.println(".... Test::testTransportURISyntaxException"); + int scaleout = 12; + ITargetURI targetUrl = new HttpTargetURI("http://localhost:"+httpPort+"/"+app); + DefaultRegistryClient registryClient = + new DefaultRegistryClient(targetUrl); + HttpServiceTransport transport = new HttpServiceTransport(registryClient, scaleout); + transport.initialize(); + System.setProperty("MockHttpPostError", ERROR.URISyntaxException.name()); + transport.dispatch("Dummy Message"); + wait(registryClient); + + } public class TaskHandlerServlet extends HttpServlet { private static final long serialVersionUID = 1L;