001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.core.net; 015 016import java.io.IOException; 017import java.net.InetAddress; 018import java.net.Socket; 019 020import javax.net.SocketFactory; 021 022import ch.qos.logback.core.util.DelayStrategy; 023import ch.qos.logback.core.util.FixedDelay; 024 025/** 026 * Default implementation of {@link SocketConnector}. 027 * 028 * @author Carl Harris 029 * @since 1.0.12 030 */ 031public class DefaultSocketConnector implements SocketConnector { 032 033 private final InetAddress address; 034 private final int port; 035 private final DelayStrategy delayStrategy; 036 037 private ExceptionHandler exceptionHandler; 038 private SocketFactory socketFactory; 039 040 /** 041 * Constructs a new connector. 042 * 043 * @param address address of remote listener 044 * @param port port of remote listener 045 * @param initialDelay delay before initial connection attempt 046 * @param retryDelay delay after failed connection attempt 047 */ 048 public DefaultSocketConnector(InetAddress address, int port, long initialDelay, long retryDelay) { 049 this(address, port, new FixedDelay(initialDelay, retryDelay)); 050 } 051 052 /** 053 * Constructs a new connector. 054 * 055 * @param address address of remote listener 056 * @param port port of remote listener 057 * @param delayStrategy strategy for choosing the delay to impose before each 058 * connection attempt 059 */ 060 public DefaultSocketConnector(InetAddress address, int port, DelayStrategy delayStrategy) { 061 this.address = address; 062 this.port = port; 063 this.delayStrategy = delayStrategy; 064 } 065 066 /** 067 * Loops until the desired connection is established and returns the resulting 068 * connector. 069 */ 070 public Socket call() throws InterruptedException { 071 useDefaultsForMissingFields(); 072 Socket socket = createSocket(); 073 while (socket == null && !Thread.currentThread().isInterrupted()) { 074 Thread.sleep(delayStrategy.nextDelay()); 075 socket = createSocket(); 076 } 077 return socket; 078 } 079 080 private Socket createSocket() { 081 Socket newSocket = null; 082 try { 083 newSocket = socketFactory.createSocket(address, port); 084 } catch (IOException ioex) { 085 exceptionHandler.connectionFailed(this, ioex); 086 } 087 return newSocket; 088 } 089 090 private void useDefaultsForMissingFields() { 091 if (exceptionHandler == null) { 092 exceptionHandler = new ConsoleExceptionHandler(); 093 } 094 if (socketFactory == null) { 095 socketFactory = SocketFactory.getDefault(); 096 } 097 } 098 099 /** 100 * {@inheritDoc} 101 */ 102 public void setExceptionHandler(ExceptionHandler exceptionHandler) { 103 this.exceptionHandler = exceptionHandler; 104 } 105 106 /** 107 * {@inheritDoc} 108 */ 109 public void setSocketFactory(SocketFactory socketFactory) { 110 this.socketFactory = socketFactory; 111 } 112 113 /** 114 * A default {@link ExceptionHandler} that writes to {@code System.out} 115 */ 116 private static class ConsoleExceptionHandler implements ExceptionHandler { 117 118 public void connectionFailed(SocketConnector connector, Exception ex) { 119 System.out.println(ex); 120 } 121 122 } 123 124}