1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.net;
19
20 import com.google.common.base.Supplier;
21 import java.io.Closeable;
22 import java.io.IOException;
23 import java.net.InetAddress;
24 import java.net.InetSocketAddress;
25 import java.net.ServerSocket;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29
30
31
32
33
34
35
36 public final class BoundSocketMaker implements Closeable {
37 private static final Log LOG = LogFactory.getLog(BoundSocketMaker.class);
38 private final ServerSocket socket;
39
40 private BoundSocketMaker() {
41 this.socket = null;
42 }
43
44 public BoundSocketMaker(Supplier<Integer> randomPortMaker) {
45 this(InetAddress.getLoopbackAddress().getHostName(), randomPortMaker);
46 }
47
48 public BoundSocketMaker(final String hostname, Supplier<Integer> randomPortMaker) {
49 this.socket = get(hostname, randomPortMaker);
50 }
51
52 public int getPort() {
53 return this.socket.getLocalPort();
54 }
55
56
57
58
59 private ServerSocket get(String hostname, Supplier<Integer> randomPortMaker) {
60 ServerSocket ss = null;
61 int port = -1;
62 while (true) {
63 port = randomPortMaker.get();
64 try {
65 ss = new ServerSocket();
66 ss.bind(new InetSocketAddress(hostname, port));
67 break;
68 } catch (IOException ioe) {
69 LOG.warn("Failed bind", ioe);
70 try {
71 ss.close();
72 } catch (IOException ioe2) {
73 LOG.warn("FAILED CLOSE of failed bind socket", ioe2);
74 }
75 }
76 }
77 return ss;
78 }
79
80 @Override public void close() throws IOException {
81 if (this.socket != null) {
82 this.socket.close();
83 }
84 }
85 }