35 import java.util.HashSet; |
35 import java.util.HashSet; |
36 import java.util.Map; |
36 import java.util.Map; |
37 import java.util.Set; |
37 import java.util.Set; |
38 import java.util.concurrent.ExecutorService; |
38 import java.util.concurrent.ExecutorService; |
39 import java.util.concurrent.Executors; |
39 import java.util.concurrent.Executors; |
|
40 import java.util.logging.Level; |
40 import java.util.logging.Logger; |
41 import java.util.logging.Logger; |
41 import java.util.Optional; |
|
42 |
42 |
43 |
43 |
44 /** |
44 /** |
45 * Manages all the WebService HTTP servers created by JAXWS runtime. |
45 * Manages all the WebService HTTP servers created by JAXWS runtime. |
46 * |
46 * |
47 * @author Jitendra Kotamraju |
47 * @author Jitendra Kotamraju |
48 */ |
48 */ |
49 final class ServerMgr { |
49 final class ServerMgr { |
50 |
50 |
51 private static final ServerMgr serverMgr = new ServerMgr(); |
51 private static final ServerMgr serverMgr = new ServerMgr(); |
52 private static final Logger logger = |
52 private static final Logger LOGGER = |
53 Logger.getLogger( |
53 Logger.getLogger( |
54 com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server.http"); |
54 com.sun.xml.internal.ws.util.Constants.LoggingDomain + ".server.http"); |
55 private final Map<InetSocketAddress,ServerState> servers = new HashMap<InetSocketAddress,ServerState>(); |
55 private final Map<InetSocketAddress,ServerState> servers = new HashMap<>(); |
56 |
56 |
57 private ServerMgr() {} |
57 private ServerMgr() {} |
58 |
58 |
59 /** |
59 /** |
60 * Gets the singleton instance. |
60 * Gets the singleton instance. |
81 InetSocketAddress inetAddress = new InetSocketAddress(url.getHost(), |
81 InetSocketAddress inetAddress = new InetSocketAddress(url.getHost(), |
82 port); |
82 port); |
83 synchronized(servers) { |
83 synchronized(servers) { |
84 state = servers.get(inetAddress); |
84 state = servers.get(inetAddress); |
85 if (state == null) { |
85 if (state == null) { |
86 final int finalPortNum = port; |
86 ServerState free = null; |
87 Optional<ServerState> stateOpt = |
87 for (ServerState ss : servers.values()) { |
88 servers.values() |
88 if (port == ss.getServer().getAddress().getPort()) { |
89 .stream() |
89 free = ss; |
90 .filter(s -> s.getServer() |
90 break; |
91 .getAddress() |
91 } |
92 .getPort() == finalPortNum) |
92 } |
93 .findAny(); |
93 if (inetAddress.getAddress().isAnyLocalAddress() && free != null) { |
94 |
94 state = free; |
95 if (inetAddress.getAddress().isAnyLocalAddress() && |
|
96 stateOpt.isPresent()) { |
|
97 state = stateOpt.get(); |
|
98 } else { |
95 } else { |
99 logger.fine("Creating new HTTP Server at "+inetAddress); |
96 if (LOGGER.isLoggable(Level.FINE)) { |
|
97 LOGGER.fine("Creating new HTTP Server at "+inetAddress); |
|
98 } |
100 // Creates server with default socket backlog |
99 // Creates server with default socket backlog |
101 server = HttpServer.create(inetAddress, 0); |
100 server = HttpServer.create(inetAddress, 0); |
102 server.setExecutor(Executors.newCachedThreadPool()); |
101 server.setExecutor(Executors.newCachedThreadPool()); |
103 String path = url.toURI().getPath(); |
102 String path = url.toURI().getPath(); |
104 logger.fine("Creating HTTP Context at = "+path); |
103 if (LOGGER.isLoggable(Level.FINE)) { |
|
104 LOGGER.fine("Creating HTTP Context at = "+path); |
|
105 } |
105 HttpContext context = server.createContext(path); |
106 HttpContext context = server.createContext(path); |
106 server.start(); |
107 server.start(); |
107 |
108 |
108 // we have to get actual inetAddress from server, which can differ from the original in some cases. |
109 // we have to get actual inetAddress from server, which can differ from the original in some cases. |
109 // e.g. A port number of zero will let the system pick up an ephemeral port in a bind operation, |
110 // e.g. A port number of zero will let the system pick up an ephemeral port in a bind operation, |
110 // or IP: 0.0.0.0 - which is used to monitor network traffic from any valid IP address |
111 // or IP: 0.0.0.0 - which is used to monitor network traffic from any valid IP address |
111 inetAddress = server.getAddress(); |
112 inetAddress = server.getAddress(); |
112 |
113 |
113 logger.fine("HTTP server started = "+inetAddress); |
114 if (LOGGER.isLoggable(Level.FINE)) { |
|
115 LOGGER.fine("HTTP server started = "+inetAddress); |
|
116 } |
114 state = new ServerState(server, path); |
117 state = new ServerState(server, path); |
115 servers.put(inetAddress, state); |
118 servers.put(inetAddress, state); |
116 return context; |
119 return context; |
117 } |
120 } |
118 } |
121 } |
119 } |
122 } |
120 server = state.getServer(); |
123 server = state.getServer(); |
121 |
124 |
122 if (state.getPaths().contains(url.getPath())) { |
125 if (state.getPaths().contains(url.getPath())) { |
123 String err = "Context with URL path "+url.getPath()+ " already exists on the server "+server.getAddress(); |
126 String err = "Context with URL path "+url.getPath()+ " already exists on the server "+server.getAddress(); |
124 logger.fine(err); |
127 if (LOGGER.isLoggable(Level.FINE)) { |
|
128 LOGGER.fine(err); |
|
129 } |
125 throw new IllegalArgumentException(err); |
130 throw new IllegalArgumentException(err); |
126 } |
131 } |
127 |
132 |
128 logger.fine("Creating HTTP Context at = "+url.getPath()); |
133 if (LOGGER.isLoggable(Level.FINE)) { |
|
134 LOGGER.fine("Creating HTTP Context at = "+url.getPath()); |
|
135 } |
129 HttpContext context = server.createContext(url.getPath()); |
136 HttpContext context = server.createContext(url.getPath()); |
130 state.oneMoreContext(url.getPath()); |
137 state.oneMoreContext(url.getPath()); |
131 return context; |
138 return context; |
132 } catch(Exception e) { |
139 } catch(Exception e) { |
133 throw new ServerRtException("server.rt.err",e ); |
140 throw new ServerRtException("server.rt.err",e ); |