diff --git a/build-configuration/pom.xml b/build-configuration/pom.xml
index 8f5bcbca112a..e65a81f54dd0 100644
--- a/build-configuration/pom.xml
+++ b/build-configuration/pom.xml
@@ -160,7 +160,7 @@
3.1.3
3.7.7.Final
1.0
- 4.2.14.Final
+ 4.2.17.Final-SNAPSHOT
1.1.0
4.13.1
5.6.2
diff --git a/core/src/main/java/org/infinispan/configuration/global/TransportConfigurationBuilder.java b/core/src/main/java/org/infinispan/configuration/global/TransportConfigurationBuilder.java
index c707955761ec..a1eb28182ea8 100644
--- a/core/src/main/java/org/infinispan/configuration/global/TransportConfigurationBuilder.java
+++ b/core/src/main/java/org/infinispan/configuration/global/TransportConfigurationBuilder.java
@@ -165,7 +165,7 @@ public TransportConfigurationBuilder clearProperties() {
return this;
}
- public TransportConfigurationBuilder addProperty(String key, String value) {
+ public TransportConfigurationBuilder addProperty(String key, Object value) {
typedProperties.put(key, value);
return this;
}
diff --git a/core/src/main/java/org/infinispan/configuration/parsing/AbstractParserContext.java b/core/src/main/java/org/infinispan/configuration/parsing/AbstractParserContext.java
deleted file mode 100644
index 446509a93db2..000000000000
--- a/core/src/main/java/org/infinispan/configuration/parsing/AbstractParserContext.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.infinispan.configuration.parsing;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class AbstractParserContext implements ParserContext {
- List listeners = new ArrayList();
-
- @Override
- public void addParsingCompleteListener(ParserContextListener l) {
- listeners.add(l);
- }
-
- @Override
- public void fireParsingComplete() {
- for(ParserContextListener l : listeners) {
- l.parsingComplete(this);
- }
- }
-
-}
diff --git a/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java b/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java
index f8570aa06b9c..11739e51979c 100644
--- a/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java
+++ b/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java
@@ -214,7 +214,8 @@ public enum Attribute {
ZERO_CAPACITY_NODE,
INVALIDATION_THRESHOLD,
CONTEXT_INITIALIZERS,
- GROUPER;
+ GROUPER,
+ DEFAULT_CLUSTER;
private final String name;
diff --git a/core/src/main/java/org/infinispan/configuration/parsing/ConfigurationBuilderHolder.java b/core/src/main/java/org/infinispan/configuration/parsing/ConfigurationBuilderHolder.java
index 4a236863cc4a..700f8fddc0d3 100644
--- a/core/src/main/java/org/infinispan/configuration/parsing/ConfigurationBuilderHolder.java
+++ b/core/src/main/java/org/infinispan/configuration/parsing/ConfigurationBuilderHolder.java
@@ -4,8 +4,10 @@
import java.lang.ref.WeakReference;
import java.util.ArrayDeque;
+import java.util.ArrayList;
import java.util.Deque;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.infinispan.commons.configuration.io.ConfigurationReader;
@@ -22,11 +24,11 @@ public class ConfigurationBuilderHolder implements ConfigurationReaderContext {
private final GlobalConfigurationBuilder globalConfigurationBuilder;
private final Map namedConfigurationBuilders;
private ConfigurationBuilder currentConfigurationBuilder;
- private final Map, ParserContext> parserContexts;
private final WeakReference classLoader;
private final Deque scope;
private final JGroupsConfigurationBuilder jgroupsBuilder;
private NamespaceMappingParser namespaceMappingParser;
+ private List listeners = new ArrayList<>();
public ConfigurationBuilderHolder() {
this(Thread.currentThread().getContextClassLoader());
@@ -39,7 +41,6 @@ public ConfigurationBuilderHolder(ClassLoader classLoader) {
public ConfigurationBuilderHolder(ClassLoader classLoader, GlobalConfigurationBuilder globalConfigurationBuilder) {
this.globalConfigurationBuilder = globalConfigurationBuilder;
this.namedConfigurationBuilders = new HashMap<>();
- this.parserContexts = new HashMap<>();
this.jgroupsBuilder = this.globalConfigurationBuilder.transport().jgroups();
this.classLoader = new WeakReference<>(classLoader);
scope = new ArrayDeque<>();
@@ -97,23 +98,20 @@ public String getScope() {
return scope.peek();
}
- @SuppressWarnings("unchecked")
- public T getParserContext(Class extends ConfigurationParser> parserClass) {
- return (T) parserContexts.get(parserClass);
+ public void addParserListener(ConfigurationParserListener listener) {
+ listeners.add(listener);
}
- public void setParserContext(Class extends ConfigurationParser> parserClass, ParserContext context) {
- parserContexts.put(parserClass, context);
+ public void fireParserListeners() {
+ for (ConfigurationParserListener listener : listeners) {
+ listener.parsingComplete(this);
+ }
}
public ClassLoader getClassLoader() {
return classLoader.get();
}
- Map, ParserContext> getParserContexts() {
- return parserContexts;
- }
-
public void validate() {
globalConfigurationBuilder.defaultCacheName().ifPresent(name -> {
if (!namedConfigurationBuilders.containsKey(name))
diff --git a/core/src/main/java/org/infinispan/configuration/parsing/ParserContextListener.java b/core/src/main/java/org/infinispan/configuration/parsing/ConfigurationParserListener.java
similarity index 54%
rename from core/src/main/java/org/infinispan/configuration/parsing/ParserContextListener.java
rename to core/src/main/java/org/infinispan/configuration/parsing/ConfigurationParserListener.java
index 551df2272d3c..182890c2f2c7 100644
--- a/core/src/main/java/org/infinispan/configuration/parsing/ParserContextListener.java
+++ b/core/src/main/java/org/infinispan/configuration/parsing/ConfigurationParserListener.java
@@ -4,11 +4,11 @@
/**
* ParserContextListener. An interface which should be implemented by listeners who wish to be
- * notified when a file has been successfully parsed. See {@link ParserContext}
+ * notified when a file has been successfully parsed.
*
* @author Tristan Tarrant
* @since 5.2
*/
-public interface ParserContextListener extends EventListener {
- void parsingComplete(ParserContext context);
+public interface ConfigurationParserListener extends EventListener {
+ void parsingComplete(ConfigurationBuilderHolder holder);
}
diff --git a/core/src/main/java/org/infinispan/configuration/parsing/Parser.java b/core/src/main/java/org/infinispan/configuration/parsing/Parser.java
index 26fe3fdde50b..84305d78b906 100644
--- a/core/src/main/java/org/infinispan/configuration/parsing/Parser.java
+++ b/core/src/main/java/org/infinispan/configuration/parsing/Parser.java
@@ -558,15 +558,34 @@ private void parseJGroupsStack(ConfigurationReader reader, ConfigurationBuilderH
}
private void parseJGroupsRelay(ConfigurationReader reader, ConfigurationBuilderHolder holder, EmbeddedJGroupsChannelConfigurator stackConfigurator) {
- String defaultStack = ParseUtils.requireSingleAttribute(reader, Attribute.DEFAULT_STACK);
+ String defaultStack = ParseUtils.requireAttributes(reader, Attribute.DEFAULT_STACK)[0];
+ String defaultCluster = "xsite";
if (holder.getJGroupsStack(defaultStack) == null) {
throw CONFIG.missingJGroupsStack(defaultStack);
}
+ for (int i = 0; i < reader.getAttributeCount(); i++) {
+ if (!ParseUtils.isNoNamespaceAttribute(reader, i))
+ continue;
+ String value = reader.getAttributeValue(i);
+ Attribute attribute = Attribute.forName(reader.getAttributeName(i));
+ switch (attribute) {
+ case DEFAULT_STACK:
+ // Already seen
+ break;
+ case DEFAULT_CLUSTER:
+ defaultCluster = value;
+ break;
+ default: {
+ throw ParseUtils.unexpectedAttribute(reader, i);
+ }
+ }
+ }
while (reader.inTag()) {
Element element = Element.forName(reader.getLocalName());
switch (element) {
case REMOTE_SITE:
String remoteSite = ParseUtils.requireAttributes(reader, Attribute.NAME)[0];
+ String cluster = defaultCluster;
String stack = defaultStack;
for (int i = 0; i < reader.getAttributeCount(); i++) {
Attribute attribute = Attribute.forName(reader.getAttributeName(i));
@@ -579,12 +598,15 @@ private void parseJGroupsRelay(ConfigurationReader reader, ConfigurationBuilderH
throw CONFIG.missingJGroupsStack(stack);
}
break;
+ case CLUSTER:
+ cluster = reader.getAttributeValue(i);
+ break;
default:
throw ParseUtils.unexpectedAttribute(reader, i);
}
}
ParseUtils.requireNoContent(reader);
- stackConfigurator.addRemoteSite(remoteSite, holder.getJGroupsStack(stack));
+ stackConfigurator.addRemoteSite(remoteSite, cluster, holder.getJGroupsStack(stack));
break;
default:
throw ParseUtils.unexpectedElement(reader);
diff --git a/core/src/main/java/org/infinispan/configuration/parsing/ParserContext.java b/core/src/main/java/org/infinispan/configuration/parsing/ParserContext.java
deleted file mode 100644
index f0230deb68bb..000000000000
--- a/core/src/main/java/org/infinispan/configuration/parsing/ParserContext.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.infinispan.configuration.parsing;
-
-/**
- * ParserContext. By using the methods declared in this interface, parsers can register listeners
- * which will be invoked when the parsing completes successfully. This is useful when configuration can
- * be completed only when the whole file has been parsed (e.g. because of the use of named references)
- *
- * @author Tristan Tarrant
- * @since 5.2
- */
-public interface ParserContext {
- void addParsingCompleteListener(ParserContextListener l);
-
- void fireParsingComplete();
-}
diff --git a/core/src/main/java/org/infinispan/configuration/parsing/ParserRegistry.java b/core/src/main/java/org/infinispan/configuration/parsing/ParserRegistry.java
index 36e82d8dd199..b4fc5ea7dd7d 100644
--- a/core/src/main/java/org/infinispan/configuration/parsing/ParserRegistry.java
+++ b/core/src/main/java/org/infinispan/configuration/parsing/ParserRegistry.java
@@ -169,9 +169,7 @@ public ConfigurationBuilderHolder parse(InputStream is, ConfigurationBuilderHold
ConfigurationReader reader = ConfigurationReader.from(is).withResolver(resourceResolver).withType(mediaType).withProperties(properties).withNamingStrategy(NamingStrategy.KEBAB_CASE).build();
parse(reader, holder);
// Fire all parsingComplete events if any
- for (ParserContext parserContext : holder.getParserContexts().values()) {
- parserContext.fireParsingComplete();
- }
+ holder.fireParserListeners();
return holder;
}
diff --git a/core/src/main/java/org/infinispan/remoting/transport/jgroups/AbstractJGroupsChannelConfigurator.java b/core/src/main/java/org/infinispan/remoting/transport/jgroups/AbstractJGroupsChannelConfigurator.java
new file mode 100644
index 000000000000..26ed52ef587e
--- /dev/null
+++ b/core/src/main/java/org/infinispan/remoting/transport/jgroups/AbstractJGroupsChannelConfigurator.java
@@ -0,0 +1,31 @@
+package org.infinispan.remoting.transport.jgroups;
+
+
+import org.jgroups.JChannel;
+import org.jgroups.stack.Protocol;
+import org.jgroups.util.SocketFactory;
+
+/**
+ * @author Tristan Tarrant <tristan@infinispan.org>
+ * @since 13.0
+ **/
+public abstract class AbstractJGroupsChannelConfigurator implements JGroupsChannelConfigurator {
+ private SocketFactory socketFactory;
+
+ @Override
+ public void setSocketFactory(SocketFactory socketFactory) {
+ this.socketFactory = socketFactory;
+ }
+
+ public SocketFactory getSocketFactory() {
+ return socketFactory;
+ }
+
+ protected JChannel applySocketFactory(JChannel channel) {
+ if (socketFactory != null) {
+ Protocol protocol = channel.getProtocolStack().getTopProtocol();
+ protocol.setSocketFactory(socketFactory);
+ }
+ return channel;
+ }
+}
diff --git a/core/src/main/java/org/infinispan/remoting/transport/jgroups/EmbeddedJGroupsChannelConfigurator.java b/core/src/main/java/org/infinispan/remoting/transport/jgroups/EmbeddedJGroupsChannelConfigurator.java
index f34dd0380658..292b7a9ae2d8 100644
--- a/core/src/main/java/org/infinispan/remoting/transport/jgroups/EmbeddedJGroupsChannelConfigurator.java
+++ b/core/src/main/java/org/infinispan/remoting/transport/jgroups/EmbeddedJGroupsChannelConfigurator.java
@@ -15,6 +15,7 @@
import org.jgroups.protocols.relay.config.RelayConfig;
import org.jgroups.stack.Configurator;
import org.jgroups.stack.Protocol;
+import org.jgroups.util.SocketFactory;
import org.jgroups.util.StackType;
/**
@@ -23,13 +24,13 @@
* @author Tristan Tarrant <tristan@infinispan.org>
* @since 10.0
**/
-public class EmbeddedJGroupsChannelConfigurator implements JGroupsChannelConfigurator {
+public class EmbeddedJGroupsChannelConfigurator extends AbstractJGroupsChannelConfigurator {
private static final String PROTOCOL_PREFIX = "org.jgroups.protocols.";
private final String name;
final List stack;
- final Map remoteSites;
+ final Map remoteSites;
public EmbeddedJGroupsChannelConfigurator(String name, List stack) {
this.name = name;
@@ -51,16 +52,12 @@ public List getProtocolStack() {
return stack;
}
- public Map getRemoteSites() {
- return remoteSites;
- }
-
public String getName() {
return name;
}
@Override
- public JChannel createChannel() throws Exception {
+ public JChannel createChannel(String name) throws Exception {
StackType stackType = org.jgroups.util.Util.getIpStackType();
List protocols = new ArrayList<>(stack.size());
for(ProtocolConfiguration c : stack) {
@@ -82,14 +79,21 @@ public JChannel createChannel() throws Exception {
if (remoteSites.size() == 0) {
throw CONFIG.jgroupsRelayWithoutRemoteSites(name);
}
- for (Map.Entry remoteSite : remoteSites.entrySet()) {
- JGroupsChannelConfigurator remoteSiteChannel = remoteSite.getValue();
+ for (Map.Entry remoteSite : remoteSites.entrySet()) {
+ JGroupsChannelConfigurator configurator = remoteSite.getValue().configurator;
+ SocketFactory socketFactory = getSocketFactory();
+ final String remoteCluster = remoteSite.getValue().cluster;
+ if (socketFactory instanceof NamedSocketFactory) {
+ // Create a new NamedSocketFactory using the remote cluster name
+ socketFactory = new NamedSocketFactory((NamedSocketFactory) socketFactory, remoteCluster);
+ }
+ configurator.setSocketFactory(socketFactory);
RelayConfig.SiteConfig siteConfig = new RelayConfig.SiteConfig(remoteSite.getKey());
- siteConfig.addBridge(new RelayConfig.BridgeConfig(remoteSiteChannel.getName()) {
+ siteConfig.addBridge(new RelayConfig.BridgeConfig(remoteCluster) {
@Override
public JChannel createChannel() throws Exception {
// TODO The bridge channel is created lazily, and Infinispan doesn't see any errors
- return remoteSiteChannel.createChannel();
+ return configurator.createChannel(getClusterName());
}
});
relay2.addSite(remoteSite.getKey(), siteConfig);
@@ -103,14 +107,14 @@ public JChannel createChannel() throws Exception {
}
}
- return new JChannel(protocols);
+ return applySocketFactory(new JChannel(protocols));
}
- public void addRemoteSite(String remoteSite, JGroupsChannelConfigurator stackConfigurator) {
+ public void addRemoteSite(String remoteSite, String cluster, JGroupsChannelConfigurator stackConfigurator) {
if (remoteSites.containsKey(remoteSite)) {
throw CONFIG.duplicateRemoteSite(remoteSite, name);
} else {
- remoteSites.put(remoteSite, stackConfigurator);
+ remoteSites.put(remoteSite, new RemoteSite(cluster, stackConfigurator));
}
}
@@ -213,4 +217,14 @@ public enum StackCombine {
REMOVE,
APPEND, // non-public
}
+
+ public static class RemoteSite {
+ final String cluster;
+ final JGroupsChannelConfigurator configurator;
+
+ public RemoteSite(String cluster, JGroupsChannelConfigurator configurator) {
+ this.cluster = cluster;
+ this.configurator = configurator;
+ }
+ }
}
diff --git a/core/src/main/java/org/infinispan/remoting/transport/jgroups/FileJGroupsChannelConfigurator.java b/core/src/main/java/org/infinispan/remoting/transport/jgroups/FileJGroupsChannelConfigurator.java
index c2041603bb79..2c3dbc03316a 100644
--- a/core/src/main/java/org/infinispan/remoting/transport/jgroups/FileJGroupsChannelConfigurator.java
+++ b/core/src/main/java/org/infinispan/remoting/transport/jgroups/FileJGroupsChannelConfigurator.java
@@ -16,7 +16,7 @@
* @author Tristan Tarrant <tristan@infinispan.org>
* @since 10.0
**/
-public class FileJGroupsChannelConfigurator implements JGroupsChannelConfigurator {
+public class FileJGroupsChannelConfigurator extends AbstractJGroupsChannelConfigurator {
private final String name;
private final String path;
private final Properties properties;
@@ -45,8 +45,8 @@ public String getName() {
}
@Override
- public JChannel createChannel() throws Exception {
- return new JChannel(this);
+ public JChannel createChannel(String name) throws Exception {
+ return applySocketFactory(new JChannel(this));
}
public String getPath() {
diff --git a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsChannelConfigurator.java b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsChannelConfigurator.java
index 22e7d92c1a66..706dad463bdb 100644
--- a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsChannelConfigurator.java
+++ b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsChannelConfigurator.java
@@ -2,6 +2,7 @@
import org.jgroups.JChannel;
import org.jgroups.conf.ProtocolStackConfigurator;
+import org.jgroups.util.SocketFactory;
/**
* @author Tristan Tarrant <tristan@infinispan.org>
@@ -10,5 +11,7 @@
public interface JGroupsChannelConfigurator extends ProtocolStackConfigurator {
String getName();
- JChannel createChannel() throws Exception;
+ JChannel createChannel(String name) throws Exception;
+
+ void setSocketFactory(SocketFactory socketFactory);
}
diff --git a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsTransport.java b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsTransport.java
index dacba2a436e2..43fadff4b645 100644
--- a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsTransport.java
+++ b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsTransport.java
@@ -108,8 +108,10 @@
import org.jgroups.protocols.relay.RouteStatusListener;
import org.jgroups.protocols.relay.SiteAddress;
import org.jgroups.protocols.relay.SiteMaster;
+import org.jgroups.stack.Protocol;
import org.jgroups.util.ExtendedUUID;
import org.jgroups.util.MessageBatch;
+import org.jgroups.util.SocketFactory;
/**
* An encapsulation of a JGroups transport. JGroups transports can be configured using a variety of
@@ -136,6 +138,7 @@ public class JGroupsTransport implements Transport {
public static final String CONFIGURATION_FILE = "configurationFile";
public static final String CHANNEL_LOOKUP = "channelLookup";
public static final String CHANNEL_CONFIGURATOR = "channelConfigurator";
+ public static final String SOCKET_FACTORY = "socketFactory";
public static final short REQUEST_FLAGS_UNORDERED =
(short) (Message.Flag.OOB.value() | Message.Flag.NO_TOTAL_ORDER.value() |
Message.Flag.DONT_BUNDLE.value());
@@ -611,8 +614,15 @@ private void buildChannel() {
if (channel == null && props.containsKey(CHANNEL_CONFIGURATOR)) {
JGroupsChannelConfigurator configurator = (JGroupsChannelConfigurator) props.get(CHANNEL_CONFIGURATOR);
+ if (props.containsKey(SOCKET_FACTORY)) {
+ SocketFactory socketFactory = (SocketFactory) props.get(SOCKET_FACTORY);
+ if (socketFactory instanceof NamedSocketFactory) {
+ ((NamedSocketFactory)socketFactory).setName(configuration.transport().clusterName());
+ }
+ configurator.setSocketFactory(socketFactory);
+ }
try {
- channel = configurator.createChannel();
+ channel = configurator.createChannel(configuration.transport().clusterName());
} catch (Exception e) {
throw CLUSTER.errorCreatingChannelFromConfigurator(configurator.getProtocolStackString(), e);
}
@@ -667,6 +677,11 @@ private void buildChannel() {
throw CLUSTER.errorCreatingChannelFromConfigFile(DEFAULT_JGROUPS_CONFIGURATION_FILE, e);
}
}
+
+ if (props.containsKey(SOCKET_FACTORY)) {
+ Protocol protocol = channel.getProtocolStack().getTopProtocol();
+ protocol.setSocketFactory((SocketFactory) props.get(SOCKET_FACTORY));
+ }
}
protected void receiveClusterView(View newView) {
diff --git a/core/src/main/java/org/infinispan/remoting/transport/jgroups/NamedSocketFactory.java b/core/src/main/java/org/infinispan/remoting/transport/jgroups/NamedSocketFactory.java
new file mode 100644
index 000000000000..c3acd748272b
--- /dev/null
+++ b/core/src/main/java/org/infinispan/remoting/transport/jgroups/NamedSocketFactory.java
@@ -0,0 +1,163 @@
+package org.infinispan.remoting.transport.jgroups;
+
+import java.io.IOException;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.MulticastSocket;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.util.Map;
+import java.util.function.BiConsumer;
+
+import javax.net.ServerSocketFactory;
+
+import org.jgroups.util.SocketFactory;
+import org.jgroups.util.Util;
+
+/**
+ * A {@link SocketFactory} which allows setting a callback to configure the sockets using a supplied name.
+ *
+ * @author Tristan Tarrant <tristan@infinispan.org>
+ * @since 13.0
+ **/
+public class NamedSocketFactory implements SocketFactory {
+ private final javax.net.SocketFactory socketFactory;
+ private final ServerSocketFactory serverSocketFactory;
+ private String name;
+ private BiConsumer socketConfigurator = (c, s) -> {};
+ private BiConsumer serverSocketConfigurator = (c, s) -> {};
+
+ public NamedSocketFactory(javax.net.SocketFactory socketFactory, ServerSocketFactory serverSocketFactory) {
+ this.socketFactory = socketFactory;
+ this.serverSocketFactory = serverSocketFactory;
+ }
+
+ NamedSocketFactory(NamedSocketFactory original, String name) {
+ this.socketFactory = original.socketFactory;
+ this.serverSocketFactory = original.serverSocketFactory;
+ this.socketConfigurator = original.socketConfigurator;
+ this.serverSocketConfigurator = original.serverSocketConfigurator;
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void setSocketConfigurator(BiConsumer socketConfigurator) {
+ this.socketConfigurator = socketConfigurator;
+ }
+
+ public void setServerSocketConfigurator(BiConsumer serverSocketConfigurator) {
+ this.serverSocketConfigurator = serverSocketConfigurator;
+ }
+
+ private Socket configureSocket(Socket socket) {
+ socketConfigurator.accept(name, socket);
+ return socket;
+ }
+
+ private ServerSocket configureSocket(ServerSocket socket) {
+ serverSocketConfigurator.accept(name, socket);
+ return socket;
+ }
+
+ @Override
+ public Socket createSocket(String s) throws IOException {
+ return configureSocket(socketFactory.createSocket());
+ }
+
+ @Override
+ public Socket createSocket(String s, String host, int port) throws IOException {
+ return configureSocket(socketFactory.createSocket(host, port));
+ }
+
+ @Override
+ public Socket createSocket(String s, InetAddress host, int port) throws IOException {
+ return configureSocket(socketFactory.createSocket(host, port));
+ }
+
+ @Override
+ public Socket createSocket(String s, String host, int port, InetAddress localHost, int localPort) throws IOException {
+ return configureSocket(socketFactory.createSocket(host, port, localHost, localPort));
+ }
+
+ @Override
+ public Socket createSocket(String s, InetAddress host, int port, InetAddress localHost, int localPort) throws IOException {
+ return configureSocket(socketFactory.createSocket(host, port, localHost, localPort));
+ }
+
+ @Override
+ public ServerSocket createServerSocket(String s) throws IOException {
+ return configureSocket(serverSocketFactory.createServerSocket());
+ }
+
+ @Override
+ public ServerSocket createServerSocket(String s, int port) throws IOException {
+ return configureSocket(serverSocketFactory.createServerSocket(port));
+ }
+
+ @Override
+ public ServerSocket createServerSocket(String s, int port, int backlog) throws IOException {
+ return configureSocket(serverSocketFactory.createServerSocket(port, backlog));
+ }
+
+ @Override
+ public ServerSocket createServerSocket(String s, int port, int backlog, InetAddress bindAddress) throws IOException {
+ return configureSocket(serverSocketFactory.createServerSocket(port, backlog, bindAddress));
+ }
+
+ public DatagramSocket createDatagramSocket(String service_name) throws SocketException {
+ return new DatagramSocket();
+ }
+
+ public DatagramSocket createDatagramSocket(String service_name, SocketAddress bindaddr) throws SocketException {
+ return new DatagramSocket(bindaddr);
+ }
+
+ public DatagramSocket createDatagramSocket(String service_name, int port) throws SocketException {
+ return new DatagramSocket(port);
+ }
+
+ public DatagramSocket createDatagramSocket(String service_name, int port, InetAddress laddr) throws SocketException {
+ return new DatagramSocket(port, laddr);
+ }
+
+ public MulticastSocket createMulticastSocket(String service_name) throws IOException {
+ return new MulticastSocket();
+ }
+
+ public MulticastSocket createMulticastSocket(String service_name, int port) throws IOException {
+ return new MulticastSocket(port);
+ }
+
+ public MulticastSocket createMulticastSocket(String service_name, SocketAddress bindaddr) throws IOException {
+ return new MulticastSocket(bindaddr);
+ }
+
+ @Override
+ public void close(Socket socket) throws IOException {
+ Util.close(socket);
+ }
+
+ @Override
+ public void close(ServerSocket serverSocket) throws IOException {
+ Util.close(serverSocket);
+ }
+
+ @Override
+ public void close(DatagramSocket datagramSocket) {
+ Util.close(datagramSocket);
+ }
+
+ @Override
+ public Map