Coverage report

  %line %branch
net.sf.infrared.agent.transport.impl.SocketWriter
0% 
0% 

 1  
 /* 
 2  
  * Copyright 2005 Tavant Technologies and Contributors
 3  
  * 
 4  
  * Licensed under the Apache License, Version 2.0 (the "License")
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  * 
 16  
  * 
 17  
  * 
 18  
  * Original Author:  kaushal.kumar (Tavant Technologies)
 19  
  * Contributor(s):   binil.thomas;
 20  
  *
 21  
  */
 22  
 package net.sf.infrared.agent.transport.impl;
 23  
 
 24  
 import org.apache.log4j.Logger;
 25  
 
 26  
 import net.sf.infrared.base.model.ApplicationStatistics;
 27  
 import net.sf.infrared.base.model.OperationStatistics;
 28  
 import net.sf.infrared.base.util.LoggingFactory;
 29  
 
 30  
 import java.io.IOException;
 31  
 import java.io.ObjectOutputStream;
 32  
 import java.io.Serializable;
 33  
 import java.net.InetAddress;
 34  
 import java.net.Socket;
 35  
 
 36  
 /**
 37  
  * Responsible for writing the Statistics details to a Socket in case of
 38  
  * Centralized Collection Strategy
 39  
  * 
 40  
  * @author kaushal.kumar
 41  
  * @author binil.thomas
 42  
  */
 43  0
 public class SocketWriter {
 44  0
     private static final Logger log = LoggingFactory.getLogger(SocketWriter.class);
 45  
 
 46  
     private static final int DEFAULT_PORT = 7777;
 47  
 
 48  
     private static final int DEFAULT_RECONNECTION_DELAY = 30000;
 49  
 
 50  
     private static final int RESET_FREQUENCY = 1;
 51  
     
 52  
     private ObjectOutputStream oos;
 53  
 
 54  0
     private int reconnectionDelay = DEFAULT_RECONNECTION_DELAY;
 55  
 
 56  0
     private boolean closed = false;
 57  
 
 58  
     private InetAddress address;
 59  
 
 60  0
     private int port = DEFAULT_PORT;
 61  
 
 62  0
     private int counter = 0;
 63  
 
 64  
     private Connector connector;
 65  
 
 66  0
     public SocketWriter() {
 67  0
     }
 68  
 
 69  0
     public SocketWriter(InetAddress address, int port) {
 70  0
         this.address = address;
 71  0
         this.port = port;
 72  0
         connect(address, port);
 73  0
     }
 74  
 
 75  0
     public SocketWriter(String host, int port) {
 76  0
         this.port = port;
 77  0
         this.address = getAddressByName(host);
 78  0
         connect(address, port);
 79  0
     }
 80  
 
 81  
     public synchronized void close() {
 82  0
         if (closed) {
 83  0
             return;
 84  
         }
 85  
 
 86  0
         this.closed = true;
 87  0
         cleanUp();
 88  0
     }
 89  
 
 90  
     public void cleanUp() {
 91  0
         if (oos != null) {
 92  
             try {
 93  0
                 oos.close();
 94  0
             } catch (IOException e) {
 95  0
                 log.error("CleanUp error: Could not close ObjectOutputStream", e);
 96  0
             }
 97  
         }
 98  0
     }
 99  
 
 100  
     void connect(InetAddress address, int port) {
 101  0
         if (this.address == null) {
 102  0
             return;
 103  
         }
 104  
         try {
 105  0
             cleanUp();
 106  0
             oos = new ObjectOutputStream(class="keyword">new Socket(address, port).getOutputStream());
 107  0
             if (log.isDebugEnabled()) {
 108  0
                 log.debug("SocketWriter - Connected to " + address + " on port " + port);
 109  
             }
 110  0
         } catch (IOException ex) {
 111  0
             log.error("SocketWriter - Failed to connect to " + address + " on port " + port, ex);
 112  0
             checkAndFireConnector();
 113  0
         }
 114  0
     }
 115  
 
 116  
     public void write(OperationStatistics stats) {
 117  0
         writeToStream(stats);
 118  0
     }
 119  
 
 120  
     public void write(ApplicationStatistics stats) {
 121  0
         writeToStream(stats);
 122  0
     }
 123  
 
 124  
     public void writeToStream(Serializable stats) {
 125  0
         if (stats == null) {
 126  0
             return;
 127  
         }
 128  
 
 129  0
         if (oos != null) {
 130  
             try {
 131  0
                 oos.writeObject(stats);
 132  0
                 if (log.isDebugEnabled()) {
 133  0
                     log.debug(this + " - Wrote stats");
 134  
                 }
 135  0
                 oos.flush();
 136  0
                 if (++counter >= RESET_FREQUENCY) {
 137  0
                     counter = 0;
 138  
                     // Failing to reset the object output stream every now and
 139  
                     // then creates a serious memory leak.
 140  0
                     log.debug(this + " - Doing oos.reset()");
 141  0
                     oos.reset();
 142  
                 }
 143  0
             } catch (Throwable th) {
 144  0
                 oos = null;
 145  0
                 log.warn("Detected problem with connection", th);
 146  0
                 checkAndFireConnector();
 147  0
             } 
 148  
         }
 149  0
     }
 150  
     
 151  
     public boolean isClosed() {
 152  0
         return closed;
 153  
     }
 154  
 
 155  
     private void checkAndFireConnector() {
 156  0
         if (reconnectionDelay > 0 && connector == null) {
 157  0
             connector = new Connector();
 158  0
             connector.setDaemon(true);
 159  0
             connector.setPriority(Thread.MIN_PRIORITY);
 160  0
             connector.start();
 161  0
             log.warn("Started connector thread");
 162  
         }
 163  0
     }
 164  
 
 165  
     class Connector extends Thread {
 166  
         // we turn off logging after a while, so that we dont fill up the logs
 167  
         private static final int MAX_TRIES_TO_LOG = 5;
 168  
 
 169  
         private boolean interrupted = false;
 170  
 
 171  
         private int tries = 0;
 172  
 
 173  
         public void run() {
 174  
             Socket socket;
 175  
             while (!interrupted) {
 176  
                 try {
 177  
                     sleep(reconnectionDelay);
 178  
                     tries++;
 179  
                     socket = new Socket(address, port);
 180  
                     synchronized (this) {
 181  
                         oos = new ObjectOutputStream(socket.getOutputStream());
 182  
                         log.debug("Created socket connection with collector after " + tries
 183  
                                 + " attempts");
 184  
                         connector = null;
 185  
                         tries = 0;
 186  
                         break;
 187  
                     }
 188  
                 } catch (InterruptedException e) {
 189  
                     logError("Connector thread interrupted", e);
 190  
                     return;
 191  
                 } catch (java.net.ConnectException e) {
 192  
                     logError("Remote host '" + address.getHostName() + "' refused connection.", e);
 193  
                 } catch (Throwable th) {
 194  
                     logError("Could not connect to '" + address.getHostName() + "'", th);
 195  
                 }
 196  
             }
 197  
         }
 198  
 
 199  
         public void logError(String message, Throwable th) {
 200  
             if (tries <= MAX_TRIES_TO_LOG) {
 201  
                 log.error(message, th);
 202  
             }
 203  
             if (tries == MAX_TRIES_TO_LOG) {
 204  
                 log.error("Connector tried " + MAX_TRIES_TO_LOG + " times to connect to collector" +
 205  
                         " but failed. Connector will keep trying, but meanwhile it will not log " +
 206  
                         "the errors. It can be assumed that the errors are the same as earlier");
 207  
             }
 208  
         }
 209  
     }
 210  
 
 211  
     private static InetAddress getAddressByName(String host) {
 212  
         try {
 213  0
             return InetAddress.getByName(host);
 214  0
         } catch (Exception ex) {
 215  0
             log.error("SocketWriter - failed to get InetAddress of host " + host, ex);
 216  0
             return null;
 217  
         }
 218  
     }
 219  
 
 220  
     public void setReconnectionDelay(int delay) {
 221  0
         this.reconnectionDelay = delay;
 222  0
     }
 223  
 
 224  
     public int getReconnectionDelay() {
 225  0
         return reconnectionDelay;
 226  
     }
 227  
 
 228  
     public boolean isConnected() {
 229  0
         return (connector == null) || (! connector.isAlive());
 230  
     }
 231  
 
 232  
     public String toString() {
 233  0
         return "SocketWriter (address = " + address + ", port = " + port
 234  
                 + (isConnected() ? "" : "not ") + " connected)";
 235  
     }
 236  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.