You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by ha...@apache.org on 2006/03/14 16:16:54 UTC

svn commit: r385815 - /webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/

Author: hawkeye
Date: Tue Mar 14 07:16:48 2006
New Revision: 385815

URL: http://svn.apache.org/viewcvs?rev=385815&view=rev
Log:
Improved the closing and opening of connections.

Added:
    webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ChildHandler.java
Modified:
    webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ClientReturner.java
    webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServer.java
    webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServerThread.java
    webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ResponseSender.java
    webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/StopMockServer.java
    webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/StopTCPMonitor.java
    webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TCPMonitor.java
    webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientListener.java
    webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientThread.java

Added: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ChildHandler.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ChildHandler.java?rev=385815&view=auto
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ChildHandler.java (added)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ChildHandler.java Tue Mar 14 07:16:48 2006
@@ -0,0 +1,54 @@
+/*
+ * Created on 14-Mar-2006
+ *
+ */
+package org.apache.test;
+
+import java.util.Vector;
+
+/**
+ * @author hawkeye
+ * Connection handlers handleconnections and have a common goal of ensuring that they are 
+ * all closed when they need to be
+ */
+public abstract class ChildHandler
+{
+    protected Vector children;
+    protected ChildHandler()
+    {
+        System.out.println( "Constructing "+this);
+        children=new Vector();
+        
+    }
+    /**
+     * This method can be overridden to do specific things for the class but this superclass methodf
+     * should always be called  
+     *
+     */
+    protected void close()
+    {
+        System.out.println( "Closing "+this);
+        for(int i=0; i<children.size(); i++)
+        {
+            ChildHandler child = (ChildHandler)children.remove(i);
+            child.close();
+        }
+        children=null;
+        System.out.println( "Closed "+this);
+    }
+    protected void addChild(ChildHandler handler)
+    {
+        children.add(handler);
+    }
+    
+    public String toString()
+    {
+        String name = this.getClass().getName(); 
+        return name;
+    }
+    public void finalize()throws Throwable
+    {
+        System.out.println( "Destroying: "+this);
+        super.finalize();
+    }
+}

Modified: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ClientReturner.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ClientReturner.java?rev=385815&r1=385814&r2=385815&view=diff
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ClientReturner.java (original)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ClientReturner.java Tue Mar 14 07:16:48 2006
@@ -21,14 +21,17 @@
 /**
  * TestClientThread is a child thread of TestClientListener and handles all
  * communication between the original requestor and the TCPMonitor class.
+ * This class is responsible for the serviceSocket that is given to it.
  * 
  * @author Andrew Perry, hawkeye
  * @since 1.0
  * @see TestClientListener
  */
 
-public class ClientReturner extends Thread
+public class ClientReturner extends ChildHandler implements Runnable
 {
+    // socket to the service;
+    private Socket serviceSocket;
     boolean                  continueToRun        =true;
     private static int       number               =0;
 
@@ -58,6 +61,7 @@
         this(clientSocket);
         //        System.out.println( "ClientReturner(): entry");
         // create the reader from the server
+        this.serviceSocket = serviceSocket;
         serverResponseStream=new BufferedReader(new InputStreamReader(
                 serviceSocket.getInputStream( )));
 
@@ -121,11 +125,49 @@
         }
         catch (IOException exception)
         {
-            System.err
-                    .println("ClientReturner#run(): IOException when reading in response from server ");
-            exception.printStackTrace(System.err);
+            if(TCPMonitor.state<TCPMonitor.CLOSING_STATE)
+            {
+                System.err
+                	.println("ClientReturner#run(): IOException when reading in response from server ");
+                exception.printStackTrace(System.err);
+            }
+            else
+            {
+                // the tcpmon is closing so it's all fine - ignore.
+            }
         }
         System.out.println( "ClientReturner#run(): exit");
+    }
+    
+    protected void close()
+    {
+        continueToRun=false;
+        try
+        {
+            serviceSocket.close();
+        }
+        catch(IOException exception)
+        {
+            exception.printStackTrace(System.err);
+        }
+        try
+        {
+            serverResponseStream.close();
+        }
+        catch(IOException exception)
+        {
+            exception.printStackTrace(System.err);
+        }
+        
+        try
+        {
+            streamToClient.close();
+        }
+        catch(IOException exception)
+        {
+            exception.printStackTrace(System.err);
+        }
+        super.close();
     }
 
 }

Modified: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServer.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServer.java?rev=385815&r1=385814&r2=385815&view=diff
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServer.java (original)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServer.java Tue Mar 14 07:16:48 2006
@@ -23,6 +23,10 @@
 import java.net.Socket;
 import java.net.SocketException;
 import java.net.SocketTimeoutException;
+import java.rmi.server.SocketSecurityException;
+import java.util.Vector;
+
+import javax.net.SocketFactory;
 
 /**
  * This class sits listening on a port. When a client connects to it it returns a predefined response
@@ -30,17 +34,16 @@
  * @see printUsage() for further details
  */
 
-public class MockServer implements Runnable
+public class MockServer extends ChildHandler implements Runnable 
 {
     private static int SOCKET_TIMEOUT = 700000;
     // The port that we will listen on for the client to connect to
     private int           port;
     // File that contains the http responses that the client is expecting back.
     private File          responseFile;
-
-    private ServerSocket  serverSocket;
     private boolean       continueToRun =true;
-
+    ServerSocket serverSocket;
+    
     public static final void printUsage( )
     {
         System.out
@@ -117,8 +120,8 @@
         MockServerThread.cacheResponseFile(responseFile);
 
         // no point in going on if we can;'t create a server socket
-        serverSocket=new ServerSocket(port);
-        
+        serverSocket = TCPMonitor.getServerSocket(port);
+        serverSocket.setReuseAddress(true);
     }
 
 
@@ -134,15 +137,6 @@
         System.out.println("MockServer listening on port: "+port);
         System.out.println("Returning Output file: "+responseFile);
         Socket incoming=null;
-//        try
-//        {
-//            serverSocket.setSoTimeout(SOCKET_TIMEOUT);
-//        }
-//        catch (SocketException e)
-//        {
-//            // TODO Auto-generated catch block
-//            e.printStackTrace( );
-//        }
 
         do
         {
@@ -173,6 +167,7 @@
                 {
                     MockServerThread mockServer;
                     mockServer=new MockServerThread(incoming, responseFile);
+                    addChild(mockServer);
                     Thread mockServerThread = new Thread(mockServer);
                     mockServerThread.start( );
                 }
@@ -188,6 +183,12 @@
             }
         }
         while (continueToRun);
+        
+        close();
+    }
+    
+    protected void close()
+    {
         // clean up
         try
         {
@@ -198,6 +199,8 @@
             System.err.println( "MockServer#run(): IOException when closing the serverSocket: ");
             exception.printStackTrace(System.err);
         }
+        
+        super.close();
     }
 }
  

Modified: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServerThread.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServerThread.java?rev=385815&r1=385814&r2=385815&view=diff
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServerThread.java (original)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/MockServerThread.java Tue Mar 14 07:16:48 2006
@@ -24,17 +24,17 @@
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
 import java.net.Socket;
+import java.net.SocketException;
 import java.text.ParsePosition;
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Date;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 /**
  * @author hawkeye
+ * This class is responsible for handling the socket from the client.
  */
-public class MockServerThread implements Runnable
+public class MockServerThread extends ChildHandler implements Runnable
 {
     // NOTE: We read in this string plus two bytes (the end of the request)
     private static String   ENVELOPE_TAG    ="</SOAP-ENV:Envelope>";
@@ -42,6 +42,8 @@
 
     private static int      CHARBUFFER_SIZE =20000;
 
+    // Only store the socket so we can close it
+    private Socket socket;
     BufferedReader          inputStream;
     BufferedWriter          outputStream;
 
@@ -55,6 +57,8 @@
             throws IOException , StopRequestException
     {
         System.out.println("MockServerThread(): entry");
+        this.socket = socket; 
+        setSocketTimeouts();
         try
         {
             // get the input and outputstreams
@@ -78,7 +82,15 @@
         }
 
         // Now check that the first few bytes are not a stop message
-        checkForStopMessage( );
+        try
+        {
+            checkForStopMessage( );
+        }
+        catch(StopRequestException stopRequestException)
+        {
+            close();
+            throw stopRequestException;
+        }
 
         // we just ignore the incoming message because we don't store it or
         // anything
@@ -224,6 +236,7 @@
         {
             ResponseSender responseSender=new ResponseSender(responseMessage,
                     outputStream, this);
+            addChild(responseSender);
             Thread responseSenderThread=new Thread(responseSender);
             responseSenderThread.start( );
         }
@@ -362,365 +375,56 @@
 
             responses[i - 1] = new Response( newResponse);
         }
-        
+        reader.close();
         System.out.println( "MockServer got " + (responses.length - 1) + " responses");
     }
-
-//        /**
-//         * Because the repositories we use accomodate the dos2unix conversion we
-//         * have a problem. On unix the response files have the crlf converted to
-//         * just cr. this method returns the crlf !
-//         * 
-//         * The HTTP header and chunk sizes need to be delimited with CR LF's.
-//         * The 'server response' expected files used to mimic the response of a
-//         * server when performing unit tests also need to have the correct
-//         * delimiting character combinations in the fake response messages
-//         * (generated by the monitor). Problems arise because the expected
-//         * response files have been captured on different operating systems (Unix
-//         * and Windows) and then edited using a variety of editors that interpret
-//         * the CR character differently. Thus the file may be stored with or
-//         * without the CR characters. Also, the souce control application can be
-//         * set to convert a single LF character into a CR LF combination. The
-//         * outcome of all this character manipulation is that LF's may or may not
-//         * have the necessary associated CR for it to be recognised by the HTTP
-//         * transport. It is not just sufficient to look for every LF and to prefix
-//         * it with a CR because the context of that LF must be taken into
-//         * consideration. For example, if a LF is found in the HTTP header then it
-//         * definitely needs a CR prefix. This also applies when the message is
-//         * chunked and the chunk size must also be delimited by the CR LF sequence.
-//         * But, when a LF appears inside a chunk of data it should remain unchanged
-//         * unless the chunk size is different from the actual data size between
-//         * chunks, in which case the CR has probably been stripped out and needs to
-//         * be replaced. Below is a low level design of what should work in all
-//         * instances...
-//         * 
-//         * Is the message chunked?
-//         * NO: Convert all single LF sequences to CR+LF.
-//         *     NB: Because the value associated with the 'Content-Length' label is
-//         *         not used correctly, if the size of the file grows larger than the
-//         *         Content-Length value, no action is taken.
-//         *         Exit.
-//         * YES: Convert all single LF sequences to CR+LF in the HTTP header.
-//         *      Set Index = location of the first 'chunk' value.
-//         *      Read the chunk size.
-//         *      While the chunk size > 0
-//         *        Convert any single LF sequences to CR+LF that surround the chunk
-//         *        value.
-//         *        Is the character at offset Index + chunk size equal to CR or LF?
-//         *        NO: Count up the number of unaccompanied LF's in the chunk.
-//         *            Is the difference between the expected and actual chunk data
-//         *            length double the number of unaccompanied LF's?
-//         *            NO: Error - Irreconcilable differences between expected and
-//         *                        actual chunk data sizes.
-//         *                Exit.
-//         *            YES: Convert all single LF sequences to CR+LF in the chunk
-//         *                 data.
-//         *                 Continue.
-//         *            Index = Index + chunk size.
-//         *            Read the new chunk size.
-//         *            End of while.
-//         *      Exit.
-//         */
-//        private static void setCRLF( )
-//        {
-//    	    String sLF = "\n";
-//    	    String sCR = "\r";
-//    	    String sCRLF = sCR + sLF;
-//            String sContentLength = "Content-Length:";
-//    	    
-//            for( int i = 0; i < responses.length; i++)
-//            {
-//                if( responses[i] != null)
-//                {
-//                    System.out.println( "WE HAVE "+responses[i].getMessage().length);
-//    
-//                    
-//                    String sResponse = new String(responses[i].getMessage());
-//                    String sModifiedResponse = "";
-//                	boolean bChunked = sResponse.indexOf( sContentLength) == -1;
-//                	
-//                	if( bChunked)
-//                	{
-//                        System.out.println("Information - Response file is chunked.");
-//    
-//                        // Process HTTP header block.  At the end of each line in
-//                        // the header block, if there is only a LF character,
-//                        // prefix it with a CR.  The end of the HTTP header block
-//                        // is denoted by an empty line (i.e. CR LF).
-//                        String sLine;
-//                        int	iIndex = 0;
-//                        int iEoL = sResponse.indexOf( sLF, iIndex) + 1;
-//                        
-//                        do
-//                        {
-//                            sLine = getResponseLine( sResponse, sCRLF, iIndex, iEoL);
-//                            
-//                            sModifiedResponse += sLine;
-//    
-//                            // Get next line.
-//                            iIndex = iEoL;
-//    
-//                            iEoL = sResponse.indexOf( sLF, iIndex) + 1;
-//                        } while( iEoL > 0 && !sLine.equals( sCRLF));
-//    
-//                        // Immediately after the HTTP header block should be the
-//                        // first chunk_size.  All chunk_sizes are in hex. A chunk
-//                        // size gives the size in bytes of the data that follows
-//                        // the value (i.e. CR LF 2 0 0 0 CR LF <---Data---> CR LF)
-//                        // but any number of CR may be missing and need to be
-//                        // accounted for if the response file is to be processed
-//                        // correctly.
-//                        // Do some 'first time' processing to initialise the loop
-//                        // that will process the HTTP message until the chunk size
-//                        // is zero (signifying the end of the message).
-//                        sLine = getResponseLine(sResponse, sCRLF, iIndex, iEoL);
-//    
-//                        sModifiedResponse += sLine;
-//    
-//                        iIndex = iEoL;
-//    
-//                        // Evaluate chunk_size value.
-//                        int iChunkSize = Integer.parseInt( sLine.trim(), 16);
-//    
-//                        // On entry to the loop, iChunkSize is the size of the data
-//                        // chunk and iIndex is the current location that is being
-//                        // processed.
-//                        do
-//                        {
-//    	                    int	iChunkDataBlockBegin = iIndex;
-//    	                    int	iChunkDataBlockEnd = iIndex + iChunkSize;
-//    	                    int	iResponseSize = sResponse.length();
-//    
-//    	                    // If the chunk data block end is greater than the size
-//    	                    // of the file, then the size of the chunk is incorrect.
-//    	                    // If '###' was used, then the size of the chunk is
-//    	                    // incorrectly calculated to include the chunk size in
-//    	                    // the chunk length. 
-//    	                    if( iChunkDataBlockEnd > iResponseSize)
-//    	                    {
-//    	                        if( iChunkDataBlockEnd - iResponseSize > 1)
-//    	                        {
-//    	                            System.out.println( "Warning - The chunk size is greater than the file size by " + (iChunkDataBlockEnd - iResponseSize) + " bytes.");
-//    	                        }
-//    	                        
-//    	                        iChunkDataBlockEnd = sResponse.lastIndexOf( "0") - 1;
-//    	                        iChunkSize = iChunkDataBlockEnd - iIndex;
-//    	                    }
-//    	                    
-//    	                    String sChunkDataBlock = sResponse.substring( iChunkDataBlockBegin, iChunkDataBlockEnd);
-//    
-//    	                    iIndex += iChunkSize;
-//    
-//    	                    // Check that offset from current position + chunk_size is
-//    	                    // another chunk_size.
-//                            iEoL = sResponse.indexOf( sLF, iIndex) + 1;
-//    
-//                            if( iEoL == 0)
-//                            {
-//                                // There are no more LF's in the file.  This is
-//                                // probably because there is no LF at the end of
-//                                // the file.  Assume so and make sLine = "0".
-//    	                        System.out.println( "Warning - The response file chunk sizes appear to be wrong.");
-//    	                        
-//    	                        sLine = "";
-//                            }
-//                            else
-//                            {
-//                                // Check if the chunk data size is bigger than
-//                                // expected.  If it is, then count up the number
-//                                // of CR LF in the data chunk and iff this number
-//                                // matches the difference is actual and expected
-//                                // chunk size, then remove all CR within the data
-//                                // chunk.
-//                                if( iEoL - iIndex > 2)
-//                                {
-//                                    int	iLFCount = 0;
-//                                    int	iLF = 0;
-//                                    
-//                                    while( (iLF = sChunkDataBlock.indexOf( sLF, iLF) + 1) > 0)
-//                                    {
-//                                        iLFCount++;
-//                                    }
-//                                    
-//                                    if( iLFCount == (iEoL - iIndex - 2))
-//                                    {
-//                                        System.out.println( "Warning - chunk data size is larger than expected.  Additional CR may have been added to LF within data chunk.  Fixed.");
-//                                        
-//                                        sChunkDataBlock = sChunkDataBlock.replaceAll( sCRLF, sLF);
-//                                    }
-//                                    else
-//                                    {
-//                                        System.out.println( "Warning - chunk data size is larger than expected.  Additional CR may have been added to LF within data chunk.  Unable to fix.");
-//                                    }
-//                                }
-//                                
-//                                sLine = getResponseLine( sResponse, sCRLF, iIndex, iEoL);
-//    
-//                                sChunkDataBlock += sLine;
-//    
-//    	                        // Get next line.
-//    	                        iIndex = iEoL;
-//    	
-//    	                        iEoL = sResponse.indexOf( sLF, iIndex) + 1;
-//    	
-//    	                        if( iEoL == 0)
-//    	                        {
-//    	                            // There are no more LF's in the file.  This is
-//    	                            // probably because there is no LF at the end of
-//    	                            // the file.  Assume so and make sLine = "0".
-//    		                        System.out.println( "Warning - The response file does not end with a LF.");
-//    	                            
-//    	                            sLine = "0" + sLF;
-//    	                        }
-//    	                        else
-//    	                        {
-//    	                            sLine = getResponseLine( sResponse, sCRLF, iIndex, iEoL);
-//    	                        }
-//    	                        
-//    		                    if( !isStringAHexNumber( sLine.trim()))
-//    		                    {
-//    		                        // Next chunk_size not found at position.  Count the
-//    		                        // number of LF's in the block.  Check if when this
-//    		                        // number * 2 is added to the offset that the pointer
-//    		                        // now points to the next chunk_size.
-//    		                        System.out.println( "Error - The next chunk_size was not found in the correct position.  Check that the contents of the chunked data between " + iChunkDataBlockBegin + " and " + iChunkDataBlockEnd + " is correct.");
-//    		                    }
-//                            }
-//    
-//    	                    sModifiedResponse += sChunkDataBlock;
-//    	                    sModifiedResponse += sLine;
-//    
-//    	                    iIndex = iEoL;
-//    	                    
-//    	                    // Evaluate chunk_size value.
-//    	                    if( sLine.trim().length() > 0 && isStringAHexNumber( sLine.trim()))
-//    	                    {
-//    	                        iChunkSize = Integer.parseInt( sLine.trim(), 16);
-//    	                    }
-//    	                    else
-//    	                    {
-//    	                        System.out.println( "Warning - The response file does not appear to end with a 0 and LF characters.");
-//    	                        
-//    	                        iChunkSize = 0;
-//    	                    }
-//                        } while( iChunkSize > 0);
-//    
-//                        // Now put it back into the responses
-//                        responses[i] = new Response(sModifiedResponse);
-//                        
-//                	}
-//                	else
-//                	{
-//                        if (System.getProperty("os.name").toLowerCase( ).startsWith("windows"))
-//                        {
-//                            System.out
-//                                    .println("Windows operating system - not converting crlf's");
-//                        }
-//                        else
-//                        {
-//                            String request=new String(responses[i].getMessage());
-//    
-//                            // check the last two digits for CRLF - if they
-//                            // are LFLF
-//                            // then this is wrong
-//                            // e.g. 0a 0a converts to 0d0a 0d0a
-//                            // I'm doing it using a matcher because this
-//                            // could get
-//                            // complicated !
-//                            Pattern pattern=Pattern.compile("\n");
-//                            Matcher matcher=pattern.matcher(request);
-//                            StringBuffer stringBuffer=new StringBuffer( );
-//    
-//                            while (matcher.find( ))
-//                            {
-//                                char[] tmpStr=matcher.group( ).toCharArray( );
-//                                matcher.appendReplacement(stringBuffer, "\r\n");
-//                            }
-//                            
-//                            matcher.appendTail(stringBuffer);
-//                            
-//                            // Now put it back into the responses
-//                            responses[i]=new Response(stringBuffer.toString( ));
-//                        }
-//                    }
-//                }
-//            }
-//    
-//            // Irrespective of platform ensure that all responses end with \r\n\r\n
-//            for(int i=0; i<responses.length; i++)
-//            {
-//                if (responses[i]!=null)
-//                {
-//                    String request=new String(responses[i].getMessage());
-//                    // this pattern looks for any chars then any non whitespace followed directly by the EOF 
-//                    Pattern pattern=Pattern.compile("(.*)(\\s)*$");
-//                    Matcher matcher=pattern.matcher(request);
-//                    StringBuffer stringBuffer=new StringBuffer("");
-//                    // We should only find one occurence (if any) of the sequence
-//                    if(matcher.find())
-//                    {
-//                        System.out.println( "MATCHED");
-//                        // and replace them with the proper sentence !
-//                        matcher.appendReplacement(stringBuffer, "$1\r\n\r\n");
-//                    }
-//                    else
-//                    {
-//                        System.out.println( "NOT MATCHED");
-//                        // We did not find the sequence so just tack on the grouping we need.
-//                        stringBuffer.append(request);
-//                        stringBuffer.append("\r\n\r\n");
-//                        
-//                    }
-//                    // Now put it back into the responses
-//                    responses[i]=new Response(stringBuffer.toString( ));
-//                }
-//            }
-//            
-//    //        System.out.println( "*******************************************");
-//    //        System.out.println( responses[1]);
-//        }
-
-    /**
-     * @param sResponse
-     * @param sCRLF
-     * @param iIndex
-     * @param iEOL
-     */
-//    private static String getResponseLine(String sResponse, String sCRLF, int iIndex, int iEOL)
-//    {
-//        String sLine = sResponse.substring( iIndex, iEOL);
-//
-//        if( (!sLine.endsWith( sCRLF)) && (iEOL > iIndex))
-//        {
-//            sLine = sResponse.substring( iIndex, iEOL - 1) + sCRLF;
-//        }
-//        
-//        return sLine;
-//    }
-    
-//    private static boolean isStringAHexNumber( String sValue)
-//    {
-//        boolean bOutcome = true;
-//        String sValidChars = "0123456789ABCDEFabcdef";
-//        int iIndex = 0;
-//        
-//        while( bOutcome && iIndex < sValue.length())
-//        {
-//            if( sValidChars.indexOf( sValue.substring( iIndex, iIndex + 1)) == -1)
-//            {
-//                bOutcome = false;
-//            }
-//            else
-//            {
-//                iIndex++;
-//            }
-//        }
-//        
-//        return bOutcome;
-//    }
-    
+   
     public void setClosedConnection(boolean closedConnection)
     {
         this.closedConnection = closedConnection;
+    }
+    
+    /**
+     * Ensure the input and outpustreams are closed
+     */
+    protected void close()
+    {
+        try
+        {
+            socket.close();
+        }
+        catch(IOException exception)
+        {
+            exception.printStackTrace(System.err);
+        }
+        try
+        {
+            inputStream.close();
+        }
+        catch(IOException exception)
+        {
+            exception.printStackTrace(System.err);
+        }
+        
+        try
+        {
+            outputStream.close();
+        }
+        catch(IOException exception)
+        {
+            exception.printStackTrace(System.err);
+        }
+        
+        // just to make sure - clean up the response files
+        responses = null;
+        super.close();
+    }
+
+    private void setSocketTimeouts() throws SocketException
+    {
+        socket.setKeepAlive(false);
+        socket.setReuseAddress(true);
+        socket.setSoLinger(false, 1);
+        
     }
 }

Modified: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ResponseSender.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ResponseSender.java?rev=385815&r1=385814&r2=385815&view=diff
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ResponseSender.java (original)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/ResponseSender.java Tue Mar 14 07:16:48 2006
@@ -23,7 +23,7 @@
  * TODO To change the template for this generated type comment go to
  * Window - Preferences - Java - Code Style - Code Templates
  */
-public class ResponseSender implements Runnable
+public class ResponseSender extends ChildHandler implements Runnable
 {
     private Response response;
     private BufferedWriter writer;
@@ -38,7 +38,6 @@
         writer = writerToClient;
         parent = mockServerThread;
     }
-    
 
     /* (non-Javadoc)
      * @see java.lang.Runnable#run()
@@ -83,6 +82,22 @@
                 exception.printStackTrace(System.err);
             }
         }
+    }
+    
+    protected void close()
+    {
+        try
+        {
+            writer.close();
+        }
+        catch(IOException exception)
+        {
+            exception.printStackTrace(System.err);
+        }
+        
+        // we have not created anything so no need for super.close();
+        // however, we do it to get the debug message printed out 
+         super.close();
     }
 
 }

Modified: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/StopMockServer.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/StopMockServer.java?rev=385815&r1=385814&r2=385815&view=diff
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/StopMockServer.java (original)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/StopMockServer.java Tue Mar 14 07:16:48 2006
@@ -38,7 +38,7 @@
         try
         {
             System.out.println( "Going to send a stop message to "+hostname+":"+port);
-            socket=new Socket(hostname, port);
+            socket=TCPMonitor.getClientSocket(hostname, port);
             dos=new BufferedWriter(new OutputStreamWriter(socket
                     .getOutputStream( )));
             dos.write(STOPMOCKSERVER_STRING);
@@ -98,6 +98,7 @@
 
         StopMockServer stop=new StopMockServer(monitorHost, monitorPort);
         stop.stopMonitor( );
+        System.gc();
     }
 }
 

Modified: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/StopTCPMonitor.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/StopTCPMonitor.java?rev=385815&r1=385814&r2=385815&view=diff
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/StopTCPMonitor.java (original)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/StopTCPMonitor.java Tue Mar 14 07:16:48 2006
@@ -35,7 +35,7 @@
 		Socket socket = null;
 		BufferedWriter dos = null;
 		try {
-		socket = new Socket(hostname, port);
+		    socket = TCPMonitor.getClientSocket(hostname, port);
 			dos = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
 			dos.write(STOPTCPMON);
 			dos.flush();
@@ -77,6 +77,7 @@
 
 		StopTCPMonitor stop = new StopTCPMonitor(monitorHost, monitorPort);
 		stop.stopMonitor();
+		System.gc();
 	}
 }
 

Modified: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TCPMonitor.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TCPMonitor.java?rev=385815&r1=385814&r2=385815&view=diff
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TCPMonitor.java (original)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TCPMonitor.java Tue Mar 14 07:16:48 2006
@@ -18,6 +18,10 @@
 import java.io.BufferedWriter;
 import java.io.FileWriter;
 import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
 
 /**
  * @author perryan,hawkeye 
@@ -26,14 +30,22 @@
  * is meant to be used in a test suite scenario. where an instance of
  * this class is created per call to a test.
  */
-public class TCPMonitor
+public class TCPMonitor extends ChildHandler
 {
 
     private static TCPMonitor         singleton              =null;
     private static BufferedWriter     requestFileWriter;
     private static BufferedWriter     responseFileWriter;
     private static boolean            responseFileWriterOpen =false;
-    private static TestClientListener testClientListener     =null;
+  //  private static TestClientListener testClientListener     =null;
+    
+    
+    public static final int OPENING_STATE=0;
+    public static final int OPENED_STATE=0;
+    public static final int CLOSING_STATE=0;
+    public static final int CLOSED_STATE=0;
+    
+    public static int state;
 
     
     /**
@@ -47,6 +59,7 @@
     private TCPMonitor(int listenerPort, String serviceHost, int servicePort,
             String requestFile, String responseFile) throws IOException
     {
+        state = OPENING_STATE;
       try
       {
           requestFileWriter=new BufferedWriter(new FileWriter(requestFile));
@@ -77,10 +90,12 @@
         /*
          * Create a thread which listens for incoming requests
          */
-        testClientListener=new TestClientListener(listenerPort, serviceHost,
+        TestClientListener testClientListener=new TestClientListener(listenerPort, serviceHost,
                 servicePort);
+        addChild(testClientListener);
         Thread testClientListenerThread=new Thread(testClientListener);
         testClientListenerThread.start( );
+        state = OPENED_STATE;
     }
 
 
@@ -107,40 +122,6 @@
     
     
 
-    /**
-     * We've been told to stop by an incoming Stop request so clean up.
-     */
-    public static void stop( ) throws IOException
-    {
-        // close() should flush() the streams but let's just be sure !
-        System.out.println( "TCPMonitor#stop(): Flushing and closing the output files");
-        IOException exception=null;
-        try
-        {
-            requestFileWriter.flush( );
-            requestFileWriter.close( );
-
-            responseFileWriter.flush( );
-            responseFileWriter.close( );
-        }
-        catch (IOException ioException)
-        {
-            exception=ioException;
-        }
-        catch(NullPointerException nullPointerException)
-        {
-            nullPointerException.printStackTrace(System.err);
-        }
-        finally
-        {
-            singleton=null;
-        }
-        if (exception!=null)
-        {
-            throw exception;
-        }
-    }
-
     public void writeRequest(char[] buffer, int howManyChars)
     {
         try
@@ -227,6 +208,74 @@
         {
             exception.printStackTrace( );
         }
+    }
+    
+    protected void close()
+    {
+        // close() should flush() the streams but let's just be sure !
+        System.out.println( "TCPMonitor#close(): Flushing and closing the output files");
+        state = CLOSING_STATE;
+        IOException exception=null;
+        try
+        {
+            requestFileWriter.flush( );
+            requestFileWriter.close( );
+
+            responseFileWriter.flush( );
+            responseFileWriter.close( );
+        }
+        catch (IOException ioException)
+        {
+            exception=ioException;
+        }
+        catch(NullPointerException nullPointerException)
+        {
+            nullPointerException.printStackTrace(System.err);
+        }
+        finally
+        {
+            singleton=null;
+        }
+        if (exception!=null)
+        {
+            exception.printStackTrace(System.err);
+        }
+        System.out.println( "About to call super.close");
+        super.close();
+        System.out.println( "called super.close");
+        state = CLOSED_STATE;
+    }
+
+
+    /**
+     * @param hostname
+     * @param port
+     * @return a connected socket
+     */
+    public static Socket getClientSocket(String hostname, int port)throws SocketException, IOException
+    {
+		Socket socket = new Socket();
+		InetSocketAddress remoteAddress = new InetSocketAddress(hostname, port);
+		socket.setKeepAlive(false);
+		socket.setReuseAddress(true);
+		socket.connect(remoteAddress);
+		
+		return socket;
+		
+    }
+
+
+    /**
+     * @param port
+     * @return
+     */
+    public static ServerSocket getServerSocket(int port)throws IOException
+    {
+        ServerSocket socket = new ServerSocket();
+        socket.setReuseAddress(true);
+        InetSocketAddress sockAddress = new InetSocketAddress(port);
+        socket.bind(sockAddress);
+        return socket;
     }
     
     

Modified: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientListener.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientListener.java?rev=385815&r1=385814&r2=385815&view=diff
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientListener.java (original)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientListener.java Tue Mar 14 07:16:48 2006
@@ -29,12 +29,12 @@
  * @since 1.0
  */
 
-public class TestClientListener implements Runnable
+public class TestClientListener extends ChildHandler implements Runnable
 {
     private int     servicePort    =0;
     private String  serviceHostNme =null;
     private boolean stayAlive      =false;
-    ServerSocket    serverSocket   =null;
+    private ServerSocket    serverSocket   =null;
 
     /**
      * 
@@ -51,7 +51,7 @@
         this.servicePort=servicePort;
 
         // no point in carrying on if we can't listen to the client !
-        serverSocket=new ServerSocket(listenPort);
+        serverSocket=TCPMonitor.getServerSocket(listenPort);
     }
 
     /**
@@ -105,10 +105,11 @@
                 TestClientThread connectionToServer=null;
                 try
                 {
-
                         connectionToServer=new TestClientThread(clientSocket,
                                 serviceHostNme, servicePort);
-                    connectionToServer.start( );
+                        addChild(connectionToServer);
+                        Thread connectionToServerThread = new Thread(connectionToServer);
+                        connectionToServerThread.start( );
                 }
                 catch (StopRequestException stopRequestException)
                 {
@@ -141,34 +142,22 @@
                 }
             }
         }
-        System.out.println("Stopping monitor");
         // We've been told to stop
-        // cleanup - hmm, well, we haven't created a connectionToServerThread
-        // because that's what returned the Stop exception
-        // therefore it hasn't created a thread either so nothing to do there
         // Tell the Monitor to stop writing things out and to tidy itself up
+        // the tcpmon will call our close method in a second
+        TCPMonitor.getInstance().close( );
+    }
+    protected void close()
+    {
         try
         {
-            TCPMonitor.stop( );
-        }
-        catch (IOException exception)
-        {
-            System.err
-                    .println("Caught an IOException when stopping the monitor: "
-                            +exception);
-        }
-
-        // release our server socket
-        try
-        {
-            serverSocket.close( );
+            serverSocket.close();
         }
-        catch (IOException exception)
+        catch(IOException exception)
         {
-            System.err.println("IOException when closing serverSocket: "
-                    +exception);
+            exception.printStackTrace(System.err);
         }
+        super.close();
     }
-
 }
 

Modified: webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientThread.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientThread.java?rev=385815&r1=385814&r2=385815&view=diff
==============================================================================
--- webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientThread.java (original)
+++ webservices/axis/trunk/c/tests/utils/monitor/org/apache/test/TestClientThread.java Tue Mar 14 07:16:48 2006
@@ -18,14 +18,22 @@
 import java.io.*;
 import java.net.*;
 
-public class TestClientThread extends Thread
+/**  
+ * @author hawkeye
+ *
+ * Handles the connection from a client to the server
+ * this class is responsible for cleaning up the socket 
+ * 
+ */
+public class TestClientThread extends ChildHandler implements Runnable
 {
     private boolean          continueToRun                 =true;
     // the responder back to the client
-    private ClientReturner   clientReturner                =null;
+//    private ClientReturner   clientReturner                =null;
     // We need to keep hold of this so that we can tell what state it's in when
     // the
     // read fails
+    // and also to close it.
     private Socket           clientSocket;
 
     // I didn't want to make this global but it has to be for the constructor
@@ -60,15 +68,24 @@
     {
         //        System.out.println( "TestClientThread(3): entry");
         this.clientSocket=clientSocket;
-        IsStopMessage(clientSocket);
+        try
+        {
+            IsStopMessage(clientSocket);
+        }
+        catch(StopRequestException stopRequestException)
+        {
+            // have to close anything we've created
+            close();
+            throw stopRequestException;
+        }
         Socket serviceSocket=createSocketToServer(serviceHostName, servicePort);
         writeToServer(readBuffer, bytesRead);
 
         // OK, now we've done that we can create the new thread to stream
         // the result back to the client
-        clientReturner=new ClientReturner(clientSocket, serviceSocket);
-        clientReturner.start( );
-
+        ClientReturner clientReturner=new ClientReturner(clientSocket, serviceSocket);
+        addChild(clientReturner);
+        new Thread(clientReturner).start( );
     }
 
     private void IsStopMessage(Socket clientSocket) throws IOException,
@@ -206,7 +223,7 @@
                                 +exception);
             }
         }
-        clientReturner.continueToRun=false;
+        // clientReturner.continueToRun=false;
 
         //        System.out.println( "TestClientThread#run(): exit");
     }
@@ -220,7 +237,7 @@
         {
             try
             {
-                serviceSocket=new Socket(serviceHostName, servicePort);
+                serviceSocket=TCPMonitor.getClientSocket(serviceHostName, servicePort);
             }
             catch (UnknownHostException unknownHostException)
             {
@@ -287,6 +304,19 @@
         streamToServer.write(request, 0, bytesToWrite);
         streamToServer.flush( );
     }
-
+    
+    protected void close()
+    {
+        try
+        {
+            clientSocket.close();
+        }
+        catch(IOException exception)
+        {
+            exception.printStackTrace(System.err);
+        }
+        super.close();
+    }
+    
 }