OPENDJ-1134 (CR-2338) Introduce a class in replication for encapsulating host+port combinations
Augmented HostPort class to support the use cases mentioned in OPENDJ-1134.
Moved host splitting and port range validation to HostPort class.
HostPort.java:
Added valueOf() to parses a "host:port" URL + Added extractPort(), normalizePort(), normalizedHost(), removeExtraChars().
Moved isLocalAddress() code here from StaticUtils.
Added normalizedHost field, toNormalizedString() and toString(String) + modified hashCode() and equals() to ensure stability of the results returned by hashCode() and equals().
Added allAddresses() to hide HostPort(int).
Moved isEquivalentTo() code here from ReplicationBroker.isSameReplicationServerUrl().
HostPortTest.java:
Added.
StaticUtils.java:
Moved isLocalAddress() and related code to the HostPort class.
ReplicationBroker.java:
Moved some isSameReplicationServerUrl() to HostPort as isEquivalentTo().
*.java:
Used the new HostPort ctor everywhere.
It simplified the code in many places and also helped remove duplicated code.
ComputeBestServerTest.java:
Added ports to serverURLs to ensure tests still pass.
*Test.java:
Removed the test anti-pattern try/catch/fail.
1 files added
15 files modified
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2010 Sun Microsystems, Inc. |
| | | * Portions copyright 2011-2012 ForgeRock AS. |
| | | * Portions copyright 2011-2013 ForgeRock AS. |
| | | */ |
| | | package org.opends.server.core; |
| | | |
| | | import java.util.*; |
| | | |
| | | import org.opends.messages.Message; |
| | | |
| | | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Properties; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | | import org.opends.server.admin.server.ServerManagementContext; |
| | | import org.opends.server.admin.std.meta.GlobalCfgDefn; |
| | | import org.opends.server.admin.std.meta.GlobalCfgDefn.WorkflowConfigurationMode; |
| | | import org.opends.server.admin.std.server.GlobalCfg; |
| | | import org.opends.server.admin.std.server.RootCfg; |
| | | import org.opends.server.admin.server.ServerManagementContext; |
| | | import org.opends.server.api.AuthenticationPolicy; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.types.*; |
| | | |
| | | import static org.opends.messages.ConfigMessages.*; |
| | | |
| | | import static org.opends.server.util.ServerConstants.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines a utility that will be used to manage the set of core |
| | | * configuration attributes defined in the Directory Server. These |
| | |
| | | { |
| | | for (String server : smtpServers) |
| | | { |
| | | int colonPos = server.indexOf(':'); |
| | | if ((colonPos == 0) || (colonPos == (server.length()-1))) |
| | | { |
| | | Message message = ERR_CONFIG_CORE_INVALID_SMTP_SERVER.get(server); |
| | | throw new ConfigException(message); |
| | | } |
| | | else if (colonPos > 0) |
| | | { |
| | | try |
| | | { |
| | | int port = Integer.parseInt(server.substring(colonPos+1)); |
| | | if ((port < 1) || (port > 65535)) |
| | | { |
| | | Message message = ERR_CONFIG_CORE_INVALID_SMTP_SERVER.get(server); |
| | | throw new ConfigException(message); |
| | | // validate provided string |
| | | HostPort.valueOf(server); |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | catch (RuntimeException e) |
| | | { |
| | | Message message = ERR_CONFIG_CORE_INVALID_SMTP_SERVER.get(server); |
| | | throw new ConfigException(message, e); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | // Apply the configuration to the server. |
| | |
| | | DirectoryServer.setLookthroughLimit(globalConfig.getLookthroughLimit()); |
| | | |
| | | |
| | | ArrayList<Properties> mailServerProperties = new ArrayList<Properties>(); |
| | | List<Properties> mailServerProperties = new ArrayList<Properties>(); |
| | | Set<String> smtpServers = globalConfig.getSMTPServer(); |
| | | if ((smtpServers != null) && (! smtpServers.isEmpty())) |
| | | { |
| | | for (String smtpServer : smtpServers) |
| | | { |
| | | int colonPos = smtpServer.indexOf(':'); |
| | | if (colonPos > 0) |
| | | final Properties properties = new Properties(); |
| | | try |
| | | { |
| | | String smtpHost = smtpServer.substring(0, colonPos); |
| | | String smtpPort = smtpServer.substring(colonPos+1); |
| | | final HostPort hp = HostPort.valueOf(smtpServer); |
| | | |
| | | Properties properties = new Properties(); |
| | | properties.setProperty(SMTP_PROPERTY_HOST, smtpHost); |
| | | properties.setProperty(SMTP_PROPERTY_PORT, smtpPort); |
| | | properties.setProperty(SMTP_PROPERTY_HOST, hp.getHost()); |
| | | properties.setProperty(SMTP_PROPERTY_PORT, |
| | | String.valueOf(hp.getPort())); |
| | | properties.setProperty(SMTP_PROPERTY_CONNECTION_TIMEOUT, |
| | | SMTP_DEFAULT_TIMEOUT_VALUE); |
| | | properties.setProperty(SMTP_PROPERTY_IO_TIMEOUT, |
| | | SMTP_DEFAULT_TIMEOUT_VALUE); |
| | | mailServerProperties.add(properties); |
| | | } |
| | | else |
| | | catch (RuntimeException e) |
| | | { |
| | | Properties properties = new Properties(); |
| | | // no valid port provided |
| | | properties.setProperty(SMTP_PROPERTY_HOST, smtpServer); |
| | | mailServerProperties.add(properties); |
| | | } |
| | | mailServerProperties.add(properties); |
| | | } |
| | | } |
| | | DirectoryServer.setMailServerPropertySets(mailServerProperties); |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public boolean isConfigurationChangeAcceptable(GlobalCfg configuration, |
| | | List<Message> unacceptableReasons) |
| | | { |
| | |
| | | { |
| | | for (String server : smtpServers) |
| | | { |
| | | int colonPos = server.indexOf(':'); |
| | | if ((colonPos == 0) || (colonPos == (server.length()-1))) |
| | | { |
| | | Message message = ERR_CONFIG_CORE_INVALID_SMTP_SERVER.get(server); |
| | | unacceptableReasons.add(message); |
| | | configAcceptable = false; |
| | | } |
| | | else if (colonPos > 0) |
| | | { |
| | | try |
| | | { |
| | | int port = Integer.parseInt(server.substring(colonPos+1)); |
| | | if ((port < 1) || (port > 65535)) |
| | | // validate provided string |
| | | HostPort.valueOf(server); |
| | | } |
| | | catch (RuntimeException e) |
| | | { |
| | | Message message = ERR_CONFIG_CORE_INVALID_SMTP_SERVER.get(server); |
| | | unacceptableReasons.add(message); |
| | | configAcceptable = false; |
| | | } |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | Message message = ERR_CONFIG_CORE_INVALID_SMTP_SERVER.get(server); |
| | | unacceptableReasons.add(message); |
| | | configAcceptable = false; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Ensure that the default password policy always points to a password |
| | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public ConfigChangeResult applyConfigurationChange(GlobalCfg configuration) |
| | | { |
| | | ResultCode resultCode = ResultCode.SUCCESS; |
| | | boolean adminActionRequired = false; |
| | | ArrayList<Message> messages = new ArrayList<Message>(); |
| | | List<Message> messages = new ArrayList<Message>(); |
| | | |
| | | applyGlobalConfiguration(configuration); |
| | | |
| | |
| | | */ |
| | | package org.opends.server.extensions; |
| | | |
| | | |
| | | |
| | | import static org.opends.messages.ExtensionMessages.*; |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | | import static org.opends.server.protocols.ldap.LDAPConstants.*; |
| | | import static org.opends.server.util.StaticUtils.getExceptionMessage; |
| | | import static org.opends.server.util.StaticUtils.getFileForPath; |
| | | |
| | | import java.io.*; |
| | | import java.net.*; |
| | | import java.util.*; |
| | |
| | | import org.opends.server.types.*; |
| | | import org.opends.server.util.TimeThread; |
| | | |
| | | |
| | | import static org.opends.messages.ExtensionMessages.*; |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.protocols.ldap.LDAPConstants.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | |
| | | /** |
| | | * LDAP pass through authentication policy implementation. |
| | |
| | | private ConnectionFactory newLDAPConnectionFactory(final String hostPort) |
| | | { |
| | | // Validation already performed by admin framework. |
| | | final int colonIndex = hostPort.lastIndexOf(":"); |
| | | final String hostname = hostPort.substring(0, colonIndex); |
| | | final int port = Integer.parseInt(hostPort.substring(colonIndex + 1)); |
| | | return provider.getLDAPConnectionFactory(hostname, port, cfg); |
| | | final HostPort hp = HostPort.valueOf(hostPort); |
| | | return provider.getLDAPConnectionFactory(hp.getHost(), hp.getPort(), cfg); |
| | | } |
| | | |
| | | } |
| | |
| | | return scheduler; |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public String getCurrentTime() |
| | | { |
| | | return TimeThread.getGMTTime(); |
| | | } |
| | | |
| | | |
| | | |
| | | @Override |
| | | public long getCurrentTimeMS() |
| | | { |
| | | return TimeThread.getTime(); |
| | |
| | | final LDAPPassThroughAuthenticationPolicyCfg configuration, |
| | | final List<Message> unacceptableReasons, final String hostPort) |
| | | { |
| | | final int colonIndex = hostPort.lastIndexOf(":"); |
| | | final int port = Integer.parseInt(hostPort.substring(colonIndex + 1)); |
| | | if (port < 1 || port > 65535) |
| | | try |
| | | { |
| | | // validate provided string |
| | | HostPort.valueOf(hostPort); |
| | | return true; |
| | | } |
| | | catch (RuntimeException e) |
| | | { |
| | | if (unacceptableReasons != null) |
| | | { |
| | |
| | | } |
| | | return false; |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | package org.opends.server.protocols.jmx; |
| | | |
| | | import static org.opends.messages.ProtocolMessages.*; |
| | | import static org.opends.server.loggers.ErrorLogger.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.InetSocketAddress; |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.*; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | |
| | | import org.opends.server.api.ServerShutdownListener; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.types.ConfigChangeResult; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.HostPort; |
| | | import org.opends.server.types.InitializationException; |
| | | import org.opends.server.types.ResultCode; |
| | | import org.opends.server.types.*; |
| | | import org.opends.server.util.StaticUtils; |
| | | |
| | | |
| | | import static org.opends.messages.ProtocolMessages.*; |
| | | import static org.opends.server.loggers.ErrorLogger.*; |
| | | import static org.opends.server.types.HostPort.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | |
| | | /** |
| | | * This class defines a connection handler that will be used for |
| | |
| | | ServerShutdownListener, AlertGenerator, |
| | | ConfigurationChangeListener<JMXConnectionHandlerCfg> { |
| | | |
| | | private static final String WILDCARD_ADDRESS = "0.0.0.0"; |
| | | |
| | | /** |
| | | * Key that may be placed into a JMX connection environment map to |
| | | * provide a custom <code>javax.net.ssl.TrustManager</code> array |
| | |
| | | } |
| | | |
| | | listeners.clear(); |
| | | listeners.add(new HostPort(config.getListenPort())); |
| | | listeners.add(HostPort.allAddresses(config.getListenPort())); |
| | | |
| | | rmiConnector.finalizeConnectionHandler(portChanged); |
| | | try |
| | |
| | | } |
| | | |
| | | listeners.clear(); |
| | | listeners.add(new HostPort(WILDCARD_ADDRESS, config.getListenPort())); |
| | | listeners.add(HostPort.allAddresses(config.getListenPort())); |
| | | connectionHandlerName = "JMX Connection Handler " + config.getListenPort(); |
| | | |
| | | // Create a system property to store the JMX port the server is |
| | |
| | | */ |
| | | private void connect(String remoteServerURL, DN baseDN) |
| | | { |
| | | int separator = remoteServerURL.lastIndexOf(':'); |
| | | String port = remoteServerURL.substring(separator + 1); |
| | | String hostname = remoteServerURL.substring(0, separator); |
| | | boolean sslEncryption =replSessionSecurity.isSslEncryption(remoteServerURL); |
| | | |
| | | if (debugEnabled()) |
| | |
| | | Session session = null; |
| | | try |
| | | { |
| | | InetSocketAddress ServerAddr = new InetSocketAddress( |
| | | InetAddress.getByName(hostname), Integer.parseInt(port)); |
| | | final HostPort hp = HostPort.valueOf(remoteServerURL); |
| | | final InetSocketAddress serverAddr = new InetSocketAddress( |
| | | InetAddress.getByName(hp.getHost()), hp.getPort()); |
| | | socket.setTcpNoDelay(true); |
| | | int timeoutMS = MultimasterReplication.getConnectionTimeoutMS(); |
| | | socket.connect(ServerAddr, timeoutMS); |
| | | socket.connect(serverAddr, timeoutMS); |
| | | session = replSessionSecurity.createClientSession(socket, timeoutMS); |
| | | |
| | | ReplicationServerHandler rsHandler = new ReplicationServerHandler( |
| | |
| | | * No need validate the string format because the admin framework has |
| | | * already done it. |
| | | */ |
| | | final int index = rsUrl.lastIndexOf(":"); |
| | | final String hostname = rsUrl.substring(0, index); |
| | | final int port = Integer.parseInt(rsUrl.substring(index + 1)); |
| | | |
| | | if (port == replicationPort && isLocalAddress(hostname)) |
| | | final HostPort hp = HostPort.valueOf(rsUrl); |
| | | if (hp.getPort() == replicationPort && hp.isLocalAddress()) |
| | | { |
| | | serverURL = rsUrl; |
| | | return; |
| | |
| | | try |
| | | { |
| | | // translate the server name into IP address and keep the port number |
| | | String[] host = rsUrl.split(":"); |
| | | serversToDisconnect.add( |
| | | InetAddress.getByName(host[0]).getHostAddress() + ":" + host[1]); |
| | | final HostPort hp = HostPort.valueOf(rsUrl); |
| | | final String hostAddress = |
| | | InetAddress.getByName(hp.getHost()).getHostAddress(); |
| | | serversToDisconnect.add(hostAddress + ":" + hp.getPort()); |
| | | } |
| | | catch (IOException e) |
| | | { |
| | |
| | | */ |
| | | public static void onlyForTestsAddlocalReplicationServer(String server) |
| | | { |
| | | int separator = server.lastIndexOf(':'); |
| | | if (separator == -1) |
| | | return ; |
| | | int port = Integer.parseInt(server.substring(separator + 1)); |
| | | localPorts.add(port); |
| | | localPorts.add(HostPort.valueOf(server).getPort()); |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | private String normalizeServerURL(final String url) |
| | | { |
| | | final int separator = url.lastIndexOf(':'); |
| | | final String portString = url.substring(separator + 1); |
| | | final String hostname = url.substring(0, separator); |
| | | final HostPort hp = HostPort.valueOf(url); |
| | | try |
| | | { |
| | | InetAddress inetAddress = InetAddress.getByName(hostname); |
| | | if (isLocalAddress(inetAddress)) |
| | | InetAddress inetAddress = InetAddress.getByName(hp.getHost()); |
| | | if (HostPort.isLocalAddress(inetAddress)) |
| | | { |
| | | inetAddress = getLocalAddress(); |
| | | } |
| | | return inetAddress.getHostAddress() + ":" + portString; |
| | | return inetAddress.getHostAddress() + ":" + hp.getPort(); |
| | | } |
| | | catch (UnknownHostException e) |
| | | { |
| | | // This should not happen, but if it does then just default to the |
| | | // original URL. |
| | | Message message = ERR_COULD_NOT_SOLVE_HOSTNAME.get(hostname); |
| | | Message message = ERR_COULD_NOT_SOLVE_HOSTNAME.get(hp.getHost()); |
| | | logError(message); |
| | | return url; |
| | | } |
| | |
| | | generationId = inReplServerStartMsg.getGenerationId(); |
| | | serverId = inReplServerStartMsg.getServerId(); |
| | | serverURL = inReplServerStartMsg.getServerURL(); |
| | | final String port = serverURL.substring(serverURL.lastIndexOf(':') + 1); |
| | | final int port = HostPort.valueOf(serverURL).getPort(); |
| | | serverAddressURL = session.getRemoteAddress() + ":" + port; |
| | | DN baseDN = DN.decode(inReplServerStartMsg.getBaseDn()); |
| | | setBaseDNAndDomain(baseDN, false); |
| | |
| | | import org.opends.server.replication.protocol.*; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DebugLogLevel; |
| | | import org.opends.server.types.HostPort; |
| | | import org.opends.server.util.ServerConstants; |
| | | |
| | | import static org.opends.messages.ReplicationMessages.*; |
| | |
| | | private static boolean isSameReplicationServerUrl(String rs1Url, |
| | | String rs2Url) |
| | | { |
| | | // Get and compare ports of RS1 and RS2 |
| | | int separator1 = rs1Url.lastIndexOf(':'); |
| | | if (separator1 < 0) |
| | | { |
| | | // Not a RS url: should not happen |
| | | return false; |
| | | } |
| | | int rs1Port = Integer.parseInt(rs1Url.substring(separator1 + 1)); |
| | | |
| | | int separator2 = rs2Url.lastIndexOf(':'); |
| | | if (separator2 < 0) |
| | | { |
| | | // Not a RS url: should not happen |
| | | return false; |
| | | } |
| | | int rs2Port = Integer.parseInt(rs2Url.substring(separator2 + 1)); |
| | | |
| | | if (rs1Port != rs2Port) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | // Get and compare addresses of RS1 and RS2 |
| | | final String rs1 = rs1Url.substring(0, separator1); |
| | | final InetAddress[] rs1Addresses; |
| | | try |
| | | { |
| | | // Normalize local address to null. |
| | | rs1Addresses = isLocalAddress(rs1) ? null : InetAddress.getAllByName(rs1); |
| | | final HostPort hp1 = HostPort.valueOf(rs1Url); |
| | | final HostPort hp2 = HostPort.valueOf(rs2Url); |
| | | return hp1.isEquivalentTo(hp2); |
| | | } |
| | | catch (UnknownHostException ex) |
| | | catch (RuntimeException ex) |
| | | { |
| | | // Unknown RS: should not happen |
| | | // Not a RS url or not a valid port number: should not happen |
| | | return false; |
| | | } |
| | | |
| | | final String rs2 = rs2Url.substring(0, separator2); |
| | | final InetAddress[] rs2Addresses; |
| | | try |
| | | { |
| | | // Normalize local address to null. |
| | | rs2Addresses = isLocalAddress(rs2) ? null : InetAddress.getAllByName(rs2); |
| | | } |
| | | catch (UnknownHostException ex) |
| | | { |
| | | // Unknown RS: should not happen |
| | | return false; |
| | | } |
| | | |
| | | // Now compare addresses, if at least one match, this is the same server. |
| | | if (rs1Addresses == null && rs2Addresses == null) |
| | | { |
| | | // Both local addresses. |
| | | return true; |
| | | } |
| | | else if (rs1Addresses == null || rs2Addresses == null) |
| | | { |
| | | // One local address and one non-local. |
| | | return false; |
| | | } |
| | | else |
| | | { |
| | | // Both non-local addresses: check for overlap. |
| | | for (InetAddress inetAddress1 : rs1Addresses) |
| | | { |
| | | for (InetAddress inetAddress2 : rs2Addresses) |
| | | { |
| | | if (inetAddress2.equals(inetAddress1)) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | |
| | | private ReplicationServerInfo performPhaseOneHandshake( |
| | | String server, boolean keepConnection, boolean isECL) |
| | | { |
| | | int separator = server.lastIndexOf(':'); |
| | | String port = server.substring(separator + 1); |
| | | String hostname = server.substring(0, separator); |
| | | |
| | | final String baseDn = this.baseDN.toNormalizedString(); |
| | | |
| | | Session localSession = null; |
| | |
| | | try |
| | | { |
| | | // Open a socket connection to the next candidate. |
| | | int intPort = Integer.parseInt(port); |
| | | final HostPort hp = HostPort.valueOf(server); |
| | | InetSocketAddress serverAddr = new InetSocketAddress( |
| | | InetAddress.getByName(hostname), intPort); |
| | | InetAddress.getByName(hp.getHost()), hp.getPort()); |
| | | socket = new Socket(); |
| | | socket.setReceiveBufferSize(1000000); |
| | | socket.setTcpNoDelay(true); |
| | |
| | | for (Integer rsId : bestServers.keySet()) |
| | | { |
| | | ReplicationServerInfo replicationServerInfo = bestServers.get(rsId); |
| | | String server = replicationServerInfo.getServerURL(); |
| | | int separator = server.lastIndexOf(':'); |
| | | if (separator > 0) |
| | | final HostPort hp = |
| | | HostPort.valueOf(replicationServerInfo.getServerURL()); |
| | | if (hp.isLocalAddress()) |
| | | { |
| | | String hostname = server.substring(0, separator); |
| | | if (isLocalAddress(hostname)) |
| | | { |
| | | int port = Integer.parseInt(server.substring(separator + 1)); |
| | | if (isLocalReplicationServerPort(port)) |
| | | if (isLocalReplicationServerPort(hp.getPort())) |
| | | { |
| | | // An RS in the same VM will always have priority. |
| | | if (!filterServersInSameVM) |
| | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions Copyright 2013 ForgeRock AS |
| | | */ |
| | | package org.opends.server.types; |
| | | |
| | | import java.net.*; |
| | | import java.util.Enumeration; |
| | | import java.util.HashSet; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.server.loggers.debug.DebugTracer; |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | |
| | | /** |
| | | * This class defines a data structure that combines an address and |
| | |
| | | mayInvoke=true) |
| | | public final class HostPort |
| | | { |
| | | // The host for this object. |
| | | /** The tracer object for the debug logger. */ |
| | | private static final DebugTracer TRACER = getTracer(); |
| | | |
| | | /** |
| | | * The wildcard address allows to instruct a server to |
| | | * "listen to all addresses". |
| | | * |
| | | * @see InetSocketAddress#InetSocketAddress(int) InetSocketAddress javadoc |
| | | */ |
| | | public static final String WILDCARD_ADDRESS = "0.0.0.0"; |
| | | |
| | | |
| | | |
| | | |
| | | /** The supplied host for this object. */ |
| | | private final String host; |
| | | |
| | | // The port for this object; |
| | | /** |
| | | * The normalized host for this object. |
| | | * <p> |
| | | * Normalization consists of converting local addresses to "localhost". |
| | | */ |
| | | private final String normalizedHost; |
| | | |
| | | /** The port for this object. */ |
| | | private final int port; |
| | | |
| | | |
| | | |
| | | |
| | | // Time-stamp acts as memory barrier for networkInterfaces. |
| | | private static final long CACHED_LOCAL_ADDRESSES_TIMEOUT_MS = 30 * 1000; |
| | | private static volatile long localAddressesTimeStamp = 0; |
| | | private static Set<InetAddress> localAddresses = new HashSet<InetAddress>(); |
| | | |
| | | /** |
| | | * Creates a new {@code HostPort} object with the specified port |
| | | * number but no host. |
| | | * Returns {@code true} if the provided IPv4 or IPv6 address or host name |
| | | * represents the address of one of the interfaces on the current host |
| | | * machine. |
| | | * |
| | | * @param port The port number for this {@code HostPort} object. |
| | | * @param addressString |
| | | * The IPv4 or IPv6 address or host name. |
| | | * @return {@code true} if the provided IPv4 or IPv6 address or host name |
| | | * represents the address of one of the interfaces on the current host |
| | | * machine. |
| | | */ |
| | | public HostPort(int port) |
| | | public static boolean isLocalAddress(String addressString) |
| | | { |
| | | try |
| | | { |
| | | return isLocalAddress(InetAddress.getByName(addressString)); |
| | | } |
| | | catch (UnknownHostException e) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Returns {@code true} if the provided {@code InetAddress} represents the |
| | | * address of one of the interfaces on the current host machine. |
| | | * |
| | | * @param address |
| | | * The network address. |
| | | * @return {@code true} if the provided {@code InetAddress} represents the |
| | | * address of one of the interfaces on the current host machine. |
| | | */ |
| | | public static boolean isLocalAddress(InetAddress address) |
| | | { |
| | | return address.isLoopbackAddress() || getLocalAddresses().contains(address); |
| | | } |
| | | |
| | | /** |
| | | * Returns a Set of all the local addresses as detected by the Java |
| | | * environment from the operating system configuration. |
| | | * <p> |
| | | * The local addresses are temporarily cached to balance the cost of this |
| | | * expensive computation vs. refreshing the data that can be changed while the |
| | | * system is running. |
| | | * |
| | | * @return a Set containing all the local addresses |
| | | */ |
| | | private static Set<InetAddress> getLocalAddresses() |
| | | { |
| | | final long currentTimeStamp = System.currentTimeMillis(); |
| | | if (localAddressesTimeStamp |
| | | < (currentTimeStamp - CACHED_LOCAL_ADDRESSES_TIMEOUT_MS)) |
| | | { |
| | | // Refresh the cache. |
| | | try |
| | | { |
| | | final Enumeration<NetworkInterface> i = |
| | | NetworkInterface.getNetworkInterfaces(); |
| | | final Set<InetAddress> newLocalAddresses = new HashSet<InetAddress>(); |
| | | while (i.hasMoreElements()) |
| | | { |
| | | NetworkInterface n = i.nextElement(); |
| | | Enumeration<InetAddress> j = n.getInetAddresses(); |
| | | while (j.hasMoreElements()) |
| | | { |
| | | newLocalAddresses.add(j.nextElement()); |
| | | } |
| | | } |
| | | localAddresses = newLocalAddresses; |
| | | } |
| | | catch (SocketException e) |
| | | { |
| | | // Ignore and keep the old set. |
| | | TRACER.debugCaught(DebugLogLevel.WARNING, e); |
| | | } |
| | | localAddressesTimeStamp = currentTimeStamp; // Publishes. |
| | | } |
| | | return localAddresses; |
| | | } |
| | | |
| | | /** |
| | | * Returns a a new HostPort for all addresses, also known as a wildcard |
| | | * address. |
| | | * |
| | | * @param port |
| | | * The port number for the new {@code HostPort} object. |
| | | * @return a newly constructed HostPort object |
| | | */ |
| | | public static HostPort allAddresses(int port) |
| | | { |
| | | return new HostPort(port); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new {@code HostPort} object with the specified port number but no |
| | | * host. |
| | | * |
| | | * @param port |
| | | * The port number for this {@code HostPort} object. |
| | | */ |
| | | private HostPort(int port) |
| | | { |
| | | this.host = null; |
| | | this.port = port; |
| | | this.normalizedHost = null; |
| | | this.port = normalizePort(port); |
| | | } |
| | | |
| | | |
| | |
| | | */ |
| | | public HostPort(String host, int port) |
| | | { |
| | | this.host = host; |
| | | this.port = port; |
| | | this.host = removeExtraChars(host); |
| | | this.normalizedHost = normalizedHost(this.host); |
| | | this.port = normalizePort(port); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Creates a new {@code HostPort} object by parsing the supplied |
| | | * "hostName:port" String URL. This method also accepts IPV6 style |
| | | * "[hostAddress]:port" String URLs. |
| | | * |
| | | * @param hostPort |
| | | * a String representing the URL made of a host and a port. |
| | | * @return a new {@link HostPort} built from the supplied string. |
| | | * @throws NumberFormatException |
| | | * If the "port" in the supplied string cannot be converted to an |
| | | * int |
| | | * @throws IllegalArgumentException |
| | | * if no port could be found in the supplied string, or if the port |
| | | * is not a valid port number |
| | | */ |
| | | public static HostPort valueOf(String hostPort) throws NumberFormatException, |
| | | IllegalArgumentException |
| | | { |
| | | final int sepIndex = hostPort.lastIndexOf(':'); |
| | | if (sepIndex == -1) |
| | | { |
| | | throw new IllegalArgumentException( |
| | | "Invalid host/port string: no network port was provided in '" |
| | | + hostPort + "'"); |
| | | } |
| | | if (sepIndex == 0) |
| | | { |
| | | throw new IllegalArgumentException( |
| | | "Invalid host/port string: no host name was provided in '" + hostPort |
| | | + "'"); |
| | | } |
| | | String host = sepIndex != -1 ? hostPort.substring(0, sepIndex) : hostPort; |
| | | int port = Integer.parseInt(hostPort.substring(sepIndex + 1).trim()); |
| | | return new HostPort(host, port); |
| | | } |
| | | |
| | | /** |
| | | * Removes extra characters from the host name: leading and trailing white |
| | | * spaces, and surrounding square brackets for IPv6 addresses. |
| | | * |
| | | * @param host |
| | | * the host name to clean |
| | | * @return the cleaned up host name |
| | | */ |
| | | private String removeExtraChars(String host) |
| | | { |
| | | host = host.trim(); |
| | | final int startsWith = host.indexOf("["); |
| | | if (startsWith == -1) |
| | | { |
| | | return host; |
| | | } |
| | | return host.substring(1, host.length() - 1); |
| | | } |
| | | |
| | | /** |
| | | * Returns a normalized String representation of the supplied host. |
| | | * |
| | | * @param host |
| | | * the host address to normalize |
| | | * @return a normalized String representation of the supplied host. |
| | | * @see #normalizedHost what host normalization covers |
| | | */ |
| | | private String normalizedHost(String host) |
| | | { |
| | | if (isLocalAddress(host)) |
| | | { |
| | | return "localhost"; |
| | | } |
| | | return host; |
| | | } |
| | | |
| | | /** |
| | | * Ensures the supplied port number is valid. |
| | | * |
| | | * @param port |
| | | * the port number to validate |
| | | * @return the port number if valid |
| | | */ |
| | | private int normalizePort(int port) |
| | | { |
| | | if (1 <= port && port <= 65535) |
| | | { |
| | | return port; |
| | | } |
| | | throw new IllegalArgumentException("Invalid network port provided: " + port |
| | | + " is not included in the [1, 65535] range."); |
| | | } |
| | | |
| | | /** |
| | | * Retrieves the host for this {@code HostPort} object. |
| | | * |
| | | * @return The host for this {@code HostPort} object, or |
| | |
| | | /** |
| | | * Retrieves the port number for this {@code HostPort} object. |
| | | * |
| | | * @return The port number for this {@code HostPort} object. |
| | | * @return The valid port number in the [1, 65535] range for this |
| | | * {@code HostPort} object. |
| | | */ |
| | | public int getPort() |
| | | { |
| | | return port; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Whether the current object represents a local address. |
| | | * |
| | | * @return true if this represents a local address, false otherwise. |
| | | */ |
| | | public boolean isLocalAddress() |
| | | { |
| | | return isLocalAddress(getHost()); |
| | | } |
| | | |
| | | /** |
| | | * Retrieves a string representation of this {@code HostPort} |
| | | * object. It will be the host element (or nothing if no host was |
| | | * given) followed by a colon and the port number. |
| | | * Returns a string representation of this {@code HostPort} object. It will be |
| | | * the host element (or nothing if no host was given) followed by a colon and |
| | | * the port number. |
| | | * |
| | | * @return A string representation of this {@code HostPort} object. |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | if (host == null) |
| | | return toString(host); |
| | | } |
| | | |
| | | /** |
| | | * Returns a normalized string representation of this {@code HostPort} object. |
| | | * |
| | | * @return A string representation of this {@code HostPort} object. |
| | | * @see #normalizedHost what host normalization covers |
| | | */ |
| | | private String toNormalizedString() |
| | | { |
| | | return toString(normalizedHost); |
| | | } |
| | | |
| | | /** |
| | | * Inner computation for #toString() and {@link #toNormalizedString()}. |
| | | * |
| | | * @param hostName |
| | | * the hostName to use for this computation |
| | | * @return the String representation fo4r this object |
| | | */ |
| | | private String toString(String hostName) |
| | | { |
| | | if (hostName != null) |
| | | { |
| | | if (hostName.contains(":")) |
| | | { |
| | | return "[" + hostName + "]:" + port; |
| | | } |
| | | return hostName + ":" + port; |
| | | } |
| | | return ":" + port; |
| | | } |
| | | else |
| | | |
| | | /** |
| | | * Checks whether the supplied HostPort is an equivalent to the current |
| | | * HostPort. |
| | | * |
| | | * @param other |
| | | * the HostPort to compare to "this" |
| | | * @return true if the HostPorts are equivalent, false otherwise. False is |
| | | * also return if calling {@link InetAddress#getAllByName(String)} |
| | | * throws an UnknownHostException. |
| | | */ |
| | | public boolean isEquivalentTo(final HostPort other) |
| | | { |
| | | return host + ":" + port; |
| | | try |
| | | { |
| | | // Get and compare ports of RS1 and RS2 |
| | | if (getPort() != other.getPort()) |
| | | { |
| | | return false; |
| | | } |
| | | |
| | | // Get and compare addresses of RS1 and RS2 |
| | | // Normalize local addresses to null for fast comparison. |
| | | final InetAddress[] thisAddresses = |
| | | isLocalAddress() ? null : InetAddress.getAllByName(getHost()); |
| | | final InetAddress[] otherAddresses = |
| | | other.isLocalAddress() ? null : InetAddress.getAllByName(other |
| | | .getHost()); |
| | | |
| | | // Now compare addresses, if at least one match, this is the same server. |
| | | if (thisAddresses == null && otherAddresses == null) |
| | | { |
| | | // Both local addresses. |
| | | return true; |
| | | } |
| | | else if (thisAddresses == null || otherAddresses == null) |
| | | { |
| | | // One local address and one non-local. |
| | | return false; |
| | | } |
| | | |
| | | // Both non-local addresses: check for overlap. |
| | | for (InetAddress thisAddress : thisAddresses) |
| | | { |
| | | for (InetAddress otherAddress : otherAddresses) |
| | | { |
| | | if (thisAddress.equals(otherAddress)) |
| | | { |
| | | return true; |
| | | } |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | catch (UnknownHostException ex) |
| | | { |
| | | // Unknown RS: should not happen |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Returns {@code true} if the provided Object is a HostPort object |
| | | * with the same host name and port than this HostPort object. |
| | | * @param obj the reference object with which to compare. |
| | | * @return {@code true} if this object is the same as the obj |
| | | * argument; {@code false} otherwise. |
| | | * Returns {@code true} if the provided Object is a HostPort object with the |
| | | * same host name and port than this HostPort object. |
| | | * |
| | | * @param obj |
| | | * the reference object with which to compare. |
| | | * @return {@code true} if this object is the same as the obj argument; |
| | | * {@code false} otherwise. |
| | | */ |
| | | @Override |
| | | public boolean equals(Object obj) |
| | | { |
| | | boolean equals = false; |
| | | if (obj != null) |
| | | { |
| | | if (obj == null) |
| | | return false; |
| | | if (obj == this) |
| | | return true; |
| | | if (obj instanceof HostPort) |
| | | { |
| | | equals = true; |
| | | final HostPort other = (HostPort) obj; |
| | | return toNormalizedString().equals(other.toNormalizedString()); |
| | | } |
| | | else if (obj instanceof HostPort) |
| | | { |
| | | equals = toString().equals(obj.toString()); |
| | | } |
| | | } |
| | | return equals; |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | |
| | | * |
| | | * @return A hash code for this HostPort object. |
| | | */ |
| | | @Override |
| | | public int hashCode() |
| | | { |
| | | return toString().hashCode(); |
| | | return toNormalizedString().hashCode(); |
| | | } |
| | | |
| | | } |
| | | |
| | |
| | | * |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions copyright 2012 ForgeRock AS. |
| | | * Portions copyright 2012-2013 ForgeRock AS. |
| | | */ |
| | | package org.opends.server.types; |
| | | import org.opends.messages.Message; |
| | | |
| | | |
| | | |
| | | import java.util.Iterator; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.StringTokenizer; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.core.DirectoryServer; |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import org.opends.server.loggers.debug.DebugTracer; |
| | | |
| | | import static org.opends.messages.UtilityMessages.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.types.ResultCode.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | |
| | | |
| | | |
| | | /** |
| | | * This class defines a data structure that represents the components |
| | | * of an LDAP URL, including the scheme, host, port, base DN, |
| | |
| | | { |
| | | Message message = |
| | | ERR_LDAPURL_NO_COLON_SLASH_SLASH.get(String.valueOf(url)); |
| | | throw new DirectoryException( |
| | | ResultCode.INVALID_ATTRIBUTE_SYNTAX, message); |
| | | throw new DirectoryException(INVALID_ATTRIBUTE_SYNTAX, message); |
| | | } |
| | | else if (schemeEndPos == 0) |
| | | { |
| | | Message message = |
| | | ERR_LDAPURL_NO_SCHEME.get(String.valueOf(url)); |
| | | throw new DirectoryException( |
| | | ResultCode.INVALID_ATTRIBUTE_SYNTAX, message); |
| | | Message message = ERR_LDAPURL_NO_SCHEME.get(String.valueOf(url)); |
| | | throw new DirectoryException(INVALID_ATTRIBUTE_SYNTAX, message); |
| | | } |
| | | else |
| | | { |
| | | scheme = urlDecode(url.substring(0, schemeEndPos)); |
| | | // FIXME also need to check that the scheme is actually ldap/ldaps!! |
| | | } |
| | | |
| | | |
| | |
| | | { |
| | | break; |
| | | } |
| | | else |
| | | { |
| | | pos++; |
| | | } |
| | | } |
| | | |
| | | if (pos > startPos) |
| | | { |
| | | String hostPort = url.substring(startPos, pos); |
| | | int colonPos = hostPort.indexOf(':'); |
| | | int colonPos = hostPort.lastIndexOf(':'); |
| | | if (colonPos < 0) |
| | | { |
| | | host = urlDecode(hostPort); |
| | | } |
| | | else if (colonPos == 0) |
| | | { |
| | | Message message = |
| | | ERR_LDAPURL_NO_HOST.get(String.valueOf(url)); |
| | | throw new DirectoryException( |
| | | ResultCode.INVALID_ATTRIBUTE_SYNTAX, message); |
| | | Message message = ERR_LDAPURL_NO_HOST.get(String.valueOf(url)); |
| | | throw new DirectoryException(INVALID_ATTRIBUTE_SYNTAX, message); |
| | | } |
| | | else if (colonPos == (hostPort.length() - 1)) |
| | | { |
| | | Message message = |
| | | ERR_LDAPURL_NO_PORT.get(String.valueOf(url)); |
| | | throw new DirectoryException( |
| | | ResultCode.INVALID_ATTRIBUTE_SYNTAX, message); |
| | | Message message = ERR_LDAPURL_NO_PORT.get(String.valueOf(url)); |
| | | throw new DirectoryException(INVALID_ATTRIBUTE_SYNTAX, message); |
| | | } |
| | | else |
| | | { |
| | | host = urlDecode(hostPort.substring(0, colonPos)); |
| | | |
| | | try |
| | | { |
| | | port = Integer.parseInt(hostPort.substring(colonPos+1)); |
| | | final HostPort hp = HostPort.valueOf(hostPort); |
| | | host = urlDecode(hp.getHost()); |
| | | port = hp.getPort(); |
| | | } |
| | | catch (Exception e) |
| | | catch (NumberFormatException e) |
| | | { |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | |
| | | Message message = ERR_LDAPURL_CANNOT_DECODE_PORT.get( |
| | | String.valueOf(url), hostPort.substring(colonPos+1)); |
| | | throw new DirectoryException( |
| | | ResultCode.INVALID_ATTRIBUTE_SYNTAX, message); |
| | | throw new DirectoryException(INVALID_ATTRIBUTE_SYNTAX, message); |
| | | } |
| | | |
| | | if ((port <= 0) || (port > 65535)) |
| | | catch (IllegalArgumentException e) |
| | | { |
| | | Message message = |
| | | ERR_LDAPURL_INVALID_PORT.get(String.valueOf(url), port); |
| | | throw new DirectoryException( |
| | | ResultCode.INVALID_ATTRIBUTE_SYNTAX, message); |
| | | throw new DirectoryException(INVALID_ATTRIBUTE_SYNTAX, message); |
| | | } |
| | | } |
| | | } |
| | |
| | | * @return <CODE>true</CODE> if the object is equal to this LDAP |
| | | * URL, or <CODE>false</CODE> if not. |
| | | */ |
| | | @Override |
| | | public boolean equals(Object o) |
| | | { |
| | | if (o == null) |
| | |
| | | * |
| | | * @return The hash code for this LDAP URL. |
| | | */ |
| | | @Override |
| | | public int hashCode() |
| | | { |
| | | int hashCode = 0; |
| | |
| | | * |
| | | * @return A string representation of this LDAP URL. |
| | | */ |
| | | @Override |
| | | public String toString() |
| | | { |
| | | StringBuilder buffer = new StringBuilder(); |
| | |
| | | |
| | | import java.io.*; |
| | | import java.lang.reflect.InvocationTargetException; |
| | | import java.net.*; |
| | | import java.net.InetAddress; |
| | | import java.net.InetSocketAddress; |
| | | import java.net.ServerSocket; |
| | | import java.net.Socket; |
| | | import java.nio.ByteBuffer; |
| | | import java.nio.channels.SelectionKey; |
| | | import java.nio.channels.Selector; |
| | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns {@code true} if the provided IPv4 or IPv6 address or host name |
| | | * represents the address of one of the interfaces on the current host |
| | | * machine. |
| | | * |
| | | * @param addressString |
| | | * The IPv4 or IPv6 address or host name. |
| | | * @return {@code true} if the provided IPv4 or IPv6 address or host name |
| | | * represents the address of one of the interfaces on the current host |
| | | * machine. |
| | | */ |
| | | public static boolean isLocalAddress(String addressString) |
| | | { |
| | | try |
| | | { |
| | | return isLocalAddress(InetAddress.getByName(addressString)); |
| | | } |
| | | catch (UnknownHostException e) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Returns {@code true} if the provided {@code InetAddress} represents the |
| | | * address of one of the interfaces on the current host machine. |
| | | * |
| | | * @param address |
| | | * The network address. |
| | | * @return {@code true} if the provided {@code InetAddress} represents the |
| | | * address of one of the interfaces on the current host machine. |
| | | */ |
| | | public static boolean isLocalAddress(InetAddress address) |
| | | { |
| | | return address.isLoopbackAddress() || getLocalAddresses().contains(address); |
| | | } |
| | | |
| | | // Time-stamp acts as memory barrier for networkInterfaces. |
| | | private static final long CACHED_LOCAL_ADDRESSES_TIMEOUT_MS = 30 * 1000; |
| | | private static volatile long localAddressesTimeStamp = 0; |
| | | private static Set<InetAddress> localAddresses = new HashSet<InetAddress>(); |
| | | |
| | | private static Set<InetAddress> getLocalAddresses() |
| | | { |
| | | final long currentTimeStamp = System.currentTimeMillis(); |
| | | if (localAddressesTimeStamp |
| | | < (currentTimeStamp - CACHED_LOCAL_ADDRESSES_TIMEOUT_MS)) |
| | | { |
| | | // Refresh the cache. |
| | | try |
| | | { |
| | | final Enumeration<NetworkInterface> i = NetworkInterface |
| | | .getNetworkInterfaces(); |
| | | final Set<InetAddress> newLocalAddresses = new HashSet<InetAddress>(); |
| | | while (i.hasMoreElements()) |
| | | { |
| | | NetworkInterface n = i.nextElement(); |
| | | Enumeration<InetAddress> j = n.getInetAddresses(); |
| | | while (j.hasMoreElements()) |
| | | { |
| | | newLocalAddresses.add(j.nextElement()); |
| | | } |
| | | } |
| | | localAddresses = newLocalAddresses; |
| | | } |
| | | catch (SocketException e) |
| | | { |
| | | // Ignore and keep the old set. |
| | | TRACER.debugCaught(DebugLogLevel.WARNING, e); |
| | | } |
| | | localAddressesTimeStamp = currentTimeStamp; // Publishes. |
| | | } |
| | | return localAddresses; |
| | | } |
| | | |
| | | /** |
| | | * Closes the provided {@link Closeable}'s ignoring any errors which |
| | | * occurred. |
| | |
| | | private static final int myId3 = 3; |
| | | |
| | | // definitions for server names |
| | | private static final String WINNER = "winner"; |
| | | private static final String LOOSER1 = "looser1"; |
| | | private static final String LOOSER2 = "looser2"; |
| | | private static final String WINNER = "winner:389"; |
| | | private static final String LOOSER1 = "looser1:389"; |
| | | private static final String LOOSER2 = "looser2:389"; |
| | | |
| | | private void debugInfo(String s) |
| | | { |
| | |
| | | assertTrue(replicationDomain.isConnected()); |
| | | // Check connected server port |
| | | String serverStr = replicationDomain.getReplicationServer(); |
| | | int index = serverStr.lastIndexOf(':'); |
| | | assertTrue(index > -1, "Unable to find port number in: " + serverStr); |
| | | String rdPortStr = serverStr.substring(index + 1); |
| | | int rdPort = Integer.valueOf(rdPortStr); |
| | | assertEquals(rdPort, replServerPort); |
| | | assertEquals(HostPort.valueOf(serverStr).getPort(), replServerPort); |
| | | } |
| | | |
| | | private void initTest() throws Exception |
| | |
| | | */ |
| | | package org.opends.server.replication.plugin; |
| | | |
| | | import static org.opends.server.TestCaseUtils.*; |
| | | import static org.opends.server.loggers.ErrorLogger.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | import static org.testng.Assert.*; |
| | | |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.util.SortedSet; |
| | |
| | | import org.opends.server.replication.server.ReplServerFakeConfiguration; |
| | | import org.opends.server.replication.server.ReplicationServer; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.HostPort; |
| | | import org.opends.server.util.StaticUtils; |
| | | import org.testng.annotations.Test; |
| | | |
| | | import static org.opends.server.TestCaseUtils.*; |
| | | import static org.opends.server.loggers.ErrorLogger.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.testng.Assert.*; |
| | | |
| | | /** |
| | | * Some real connections from clients that should end up with a server with |
| | | * the right groupId if available. |
| | |
| | | findFreePorts(); |
| | | } |
| | | |
| | | private void endTest() |
| | | private void endTest() throws Exception |
| | | { |
| | | if (rd1 != null) |
| | | { |
| | |
| | | rd2 = null; |
| | | } |
| | | |
| | | try |
| | | { |
| | | // Clear any reference to a domain in synchro plugin |
| | | MultimasterReplication.deleteDomain(DN.decode(TEST_ROOT_DN_STRING)); |
| | | } catch (DirectoryException ex) |
| | | { |
| | | fail("Error deleting reference to domain: " + TEST_ROOT_DN_STRING); |
| | | } |
| | | |
| | | rs1 = clear(rs1); |
| | | rs2 = clear(rs2); |
| | |
| | | * before failing. |
| | | */ |
| | | private void checkConnection(int secTimeout, int dsId, int rsId, String msg) |
| | | throws Exception |
| | | { |
| | | |
| | | int rsPort = -1; |
| | |
| | | if (connected) |
| | | { |
| | | String serverStr = rd.getReplicationServer(); |
| | | int index = serverStr.lastIndexOf(':'); |
| | | if ((index == -1) || (index >= serverStr.length())) |
| | | fail("Enable to find port number in: " + serverStr); |
| | | String rdPortStr = serverStr.substring(index + 1); |
| | | try |
| | | { |
| | | rdPort = (new Integer(rdPortStr)).intValue(); |
| | | } catch (Exception e) |
| | | { |
| | | fail("Enable to get an int from: " + rdPortStr); |
| | | } |
| | | rdPort = HostPort.valueOf(serverStr).getPort(); |
| | | if (rdPort == rsPort) |
| | | rightPort = true; |
| | | } |
| | |
| | | } |
| | | |
| | | // Sleep 1 second |
| | | try |
| | | { |
| | | Thread.sleep(1000); |
| | | } catch (InterruptedException ex) |
| | | { |
| | | fail("Error sleeping " + stackTraceToSingleLineString(ex)); |
| | | } |
| | | nSec++; |
| | | |
| | | if (nSec > secTimeout) |
| | |
| | | /** |
| | | * Creates a new ReplicationServer. |
| | | */ |
| | | private ReplicationServer createReplicationServer(int serverId, |
| | | int groupId, String testCase) |
| | | private ReplicationServer createReplicationServer(int serverId, int groupId, |
| | | String testCase) throws Exception |
| | | { |
| | | SortedSet<String> replServers = new TreeSet<String>(); |
| | | try |
| | | { |
| | | int port = -1; |
| | | if (serverId == RS1_ID) |
| | | { |
| | |
| | | { |
| | | // 2 servers used for this test case. |
| | | replServers.add("localhost:" + rs2Port); |
| | | } else if (testCase.equals("testRSWithManyGroupIds")) |
| | | } |
| | | else if (testCase.equals("testRSWithManyGroupIds")) |
| | | { |
| | | // 3 servers used for this test case. |
| | | replServers.add("localhost:" + rs2Port); |
| | | replServers.add("localhost:" + rs3Port); |
| | | } else |
| | | } |
| | | else |
| | | fail("Unknown test case: " + testCase); |
| | | } else if (serverId == RS2_ID) |
| | | } |
| | | else if (serverId == RS2_ID) |
| | | { |
| | | port = rs2Port; |
| | | if (testCase.equals("testRSWithSameGroupIds")) |
| | | { |
| | | // 2 servers used for this test case. |
| | | replServers.add("localhost:" + rs1Port); |
| | | } else if (testCase.equals("testRSWithManyGroupIds")) |
| | | } |
| | | else if (testCase.equals("testRSWithManyGroupIds")) |
| | | { |
| | | // 3 servers used for this test case. |
| | | replServers.add("localhost:" + rs1Port); |
| | | replServers.add("localhost:" + rs3Port); |
| | | } else |
| | | fail("Unknown test case: " + testCase); |
| | | } else if (serverId == RS3_ID) |
| | | } |
| | | else if (serverId == RS3_ID) |
| | | { |
| | | port = rs3Port; |
| | | if (testCase.equals("testRSWithManyGroupIds")) |
| | |
| | | // 3 servers used for this test case. |
| | | replServers.add("localhost:" + rs2Port); |
| | | replServers.add("localhost:" + rs3Port); |
| | | } else |
| | | } |
| | | else |
| | | fail("Invalid test case: " + testCase); |
| | | } else |
| | | } |
| | | else |
| | | { |
| | | fail("Unknown replication server id."); |
| | | } |
| | |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(port, dir, 0, serverId, 0, 100, |
| | | replServers, groupId, 1000, 5000); |
| | | ReplicationServer replicationServer = new ReplicationServer(conf); |
| | | return replicationServer; |
| | | |
| | | } catch (Exception e) |
| | | { |
| | | fail("createReplicationServer " + stackTraceToSingleLineString(e)); |
| | | } |
| | | return null; |
| | | return new ReplicationServer(conf); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new ReplicationDomain. |
| | | */ |
| | | private LDAPReplicationDomain createReplicationDomain(int serverId, |
| | | int groupId, String testCase) |
| | | { |
| | | try |
| | | int groupId, String testCase) throws Exception |
| | | { |
| | | SortedSet<String> replServers = createRSListForTestCase(testCase); |
| | | DN baseDn = DN.decode(TEST_ROOT_DN_STRING); |
| | |
| | | MultimasterReplication.createNewDomain(domainConf); |
| | | replicationDomain.start(); |
| | | return replicationDomain; |
| | | |
| | | } catch (Exception e) |
| | | { |
| | | fail("createReplicationDomain " + stackTraceToSingleLineString(e)); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | package org.opends.server.replication.plugin; |
| | | |
| | | import static org.opends.server.TestCaseUtils.*; |
| | | import static org.opends.server.loggers.ErrorLogger.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | import static org.testng.Assert.*; |
| | | |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.util.SortedSet; |
| | |
| | | import org.opends.messages.Message; |
| | | import org.opends.messages.Severity; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.loggers.debug.DebugTracer; |
| | | import org.opends.server.replication.ReplicationTestCase; |
| | | import org.opends.server.replication.server.ReplServerFakeConfiguration; |
| | | import org.opends.server.replication.server.ReplicationServer; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.HostPort; |
| | | import org.opends.server.util.StaticUtils; |
| | | import org.testng.annotations.Test; |
| | | |
| | | import static org.opends.server.TestCaseUtils.*; |
| | | import static org.opends.server.loggers.ErrorLogger.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.testng.Assert.*; |
| | | |
| | | /** |
| | | * Test if the replication domain is able to switch of replication server |
| | | * if there is some replication server failure. |
| | |
| | | findFreePorts(); |
| | | } |
| | | |
| | | private void endTest() |
| | | private void endTest() throws Exception |
| | | { |
| | | if (rd1 != null) |
| | | { |
| | |
| | | rd2 = null; |
| | | } |
| | | |
| | | try |
| | | { |
| | | // Clear any reference to a domain in synchro plugin |
| | | MultimasterReplication.deleteDomain(DN.decode(TEST_ROOT_DN_STRING)); |
| | | } catch (DirectoryException ex) |
| | | { |
| | | fail("Error deleting reference to domain: " + TEST_ROOT_DN_STRING); |
| | | } |
| | | |
| | | rs1 = clear(rs1); |
| | | rs2 = clear(rs2); |
| | |
| | | rd1 = createReplicationDomain(baseDn, DS1_ID); |
| | | |
| | | // Wait a bit so that connections are performed |
| | | sleep(2000); |
| | | Thread.sleep(2000); |
| | | |
| | | // DS1 connected to RS1 ? |
| | | // Check which replication server is connected to this LDAP server |
| | |
| | | rd2 = createReplicationDomain(baseDn, DS2_ID); |
| | | |
| | | // Wait a bit so that connections are performed |
| | | sleep(3000); |
| | | Thread.sleep(3000); |
| | | |
| | | // Simulate RS1 failure |
| | | rs1.remove(); |
| | |
| | | } |
| | | } |
| | | |
| | | private void sleep(long time) |
| | | { |
| | | try |
| | | { |
| | | Thread.sleep(time); |
| | | } catch (InterruptedException ex) |
| | | { |
| | | fail("Error sleeping " + stackTraceToSingleLineString(ex)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Check connection of the provided replication domain to the provided |
| | | * replication server. Waits for connection to be ok up to secTimeout seconds |
| | | * before failing. |
| | | */ |
| | | private void checkConnection(int secTimeout, int dsId, int rsId, String msg) |
| | | throws Exception |
| | | { |
| | | |
| | | int rsPort = -1; |
| | | LDAPReplicationDomain rd = null; |
| | | switch (dsId) |
| | | { |
| | |
| | | fail("Unknown replication domain server id."); |
| | | } |
| | | |
| | | int rsPort = -1; |
| | | switch (rsId) |
| | | { |
| | | case RS1_ID: |
| | |
| | | if (connected) |
| | | { |
| | | String serverStr = rd.getReplicationServer(); |
| | | int index = serverStr.lastIndexOf(':'); |
| | | if ((index == -1) || (index >= serverStr.length())) |
| | | fail("Enable to find port number in: " + serverStr); |
| | | String rdPortStr = serverStr.substring(index + 1); |
| | | try |
| | | { |
| | | rdPort = (new Integer(rdPortStr)).intValue(); |
| | | } catch (Exception e) |
| | | { |
| | | fail("Enable to get an int from: " + rdPortStr); |
| | | } |
| | | rdPort = HostPort.valueOf(serverStr).getPort(); |
| | | if (rdPort == rsPort) |
| | | rightPort = true; |
| | | } |
| | |
| | | } |
| | | |
| | | // Sleep 1 second |
| | | try |
| | | { |
| | | Thread.sleep(1000); |
| | | } catch (InterruptedException ex) |
| | | { |
| | | fail("Error sleeping " + stackTraceToSingleLineString(ex)); |
| | | } |
| | | nSec++; |
| | | |
| | | if (nSec > secTimeout) |
| | |
| | | /** |
| | | * Creates a new ReplicationServer. |
| | | */ |
| | | private ReplicationServer createReplicationServer(int serverId, |
| | | String suffix) |
| | | private ReplicationServer createReplicationServer(int serverId, String suffix) |
| | | throws ConfigException |
| | | { |
| | | SortedSet<String> replServers = new TreeSet<String>(); |
| | | try |
| | | { |
| | | int port = -1; |
| | | if (serverId == RS1_ID) |
| | | { |
| | | port = rs1Port; |
| | | replServers.add("localhost:" + rs2Port); |
| | | } else if (serverId == RS2_ID) |
| | | } |
| | | else if (serverId == RS2_ID) |
| | | { |
| | | port = rs2Port; |
| | | replServers.add("localhost:" + rs1Port); |
| | | } else |
| | | } |
| | | else |
| | | { |
| | | fail("Unknown replication server id."); |
| | | } |
| | |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(port, dir, 0, serverId, 0, 100, |
| | | replServers); |
| | | ReplicationServer replicationServer = new ReplicationServer(conf); |
| | | return replicationServer; |
| | | |
| | | } catch (Exception e) |
| | | { |
| | | fail("createReplicationServer " + stackTraceToSingleLineString(e)); |
| | | } |
| | | return null; |
| | | return new ReplicationServer(conf); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new ReplicationDomain. |
| | | */ |
| | | private LDAPReplicationDomain createReplicationDomain(DN baseDn, int serverId) |
| | | throws Exception |
| | | { |
| | | |
| | | SortedSet<String> replServers = new TreeSet<String>(); |
| | | try |
| | | { |
| | | |
| | | // Create a domain with two replication servers |
| | | replServers.add("localhost:" + rs1Port); |
| | | replServers.add("localhost:" + rs2Port); |
| | | |
| | | DomainFakeCfg domainConf = |
| | | new DomainFakeCfg(baseDn, serverId, replServers); |
| | | DomainFakeCfg domainConf = new DomainFakeCfg(baseDn, serverId, replServers); |
| | | //domainConf.setHeartbeatInterval(500); |
| | | LDAPReplicationDomain replicationDomain = |
| | | MultimasterReplication.createNewDomain(domainConf); |
| | | replicationDomain.start(); |
| | | |
| | | return replicationDomain; |
| | | |
| | | } catch (Exception e) |
| | | { |
| | | fail("createReplicationDomain " + stackTraceToSingleLineString(e)); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private int findReplServerConnected(LDAPReplicationDomain rd) |
| | | { |
| | | int rsPort = -1; |
| | | |
| | | // First check that the Replication domain is connected |
| | | if (!rd.isConnected()) |
| | | return rsPort; |
| | | return -1; |
| | | |
| | | String serverStr = rd.getReplicationServer(); |
| | | int index = serverStr.lastIndexOf(':'); |
| | | if ((index == -1) || (index >= serverStr.length())) |
| | | fail("Enable to find port number in: " + serverStr); |
| | | rsPort = (new Integer(serverStr.substring(index + 1))); |
| | | |
| | | return rsPort; |
| | | return HostPort.valueOf(serverStr).getPort(); |
| | | } |
| | | } |
| | |
| | | */ |
| | | package org.opends.server.replication.plugin; |
| | | |
| | | import static org.opends.server.TestCaseUtils.*; |
| | | import static org.opends.server.loggers.ErrorLogger.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.util.StaticUtils.*; |
| | | import static org.testng.Assert.*; |
| | | |
| | | import java.io.File; |
| | | import java.net.InetAddress; |
| | | import java.net.UnknownHostException; |
| | |
| | | import org.opends.messages.Severity; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.admin.std.meta.ReplicationDomainCfgDefn.AssuredType; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.loggers.debug.DebugTracer; |
| | | import org.opends.server.replication.ReplicationTestCase; |
| | |
| | | import org.opends.server.replication.server.ReplServerFakeConfiguration; |
| | | import org.opends.server.replication.server.ReplicationServer; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.HostPort; |
| | | import org.opends.server.util.StaticUtils; |
| | | import org.testng.annotations.Test; |
| | | |
| | | import static org.opends.server.TestCaseUtils.*; |
| | | import static org.opends.server.loggers.ErrorLogger.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.testng.Assert.*; |
| | | |
| | | /** |
| | | * Some tests to know if at any time the view DSs and RSs have of the current |
| | | * topology is accurate, even after some connections, disconnections and |
| | |
| | | findFreePorts(); |
| | | } |
| | | |
| | | private void endTest() |
| | | private void endTest() throws Exception |
| | | { |
| | | if (rd1 != null) |
| | | { |
| | |
| | | rd6 = null; |
| | | } |
| | | |
| | | try |
| | | { |
| | | // Clear any reference to a domain in synchro plugin |
| | | MultimasterReplication.deleteDomain(DN.decode(TEST_ROOT_DN_STRING)); |
| | | } catch (DirectoryException ex) |
| | | { |
| | | fail("Error deleting reference to domain: " + TEST_ROOT_DN_STRING); |
| | | } |
| | | |
| | | if (rs1 != null) |
| | | { |
| | |
| | | rs3Port = -1; |
| | | } |
| | | |
| | | private void sleep(long time) |
| | | { |
| | | try |
| | | { |
| | | Thread.sleep(time); |
| | | } catch (InterruptedException ex) |
| | | { |
| | | fail("Error sleeping " + stackTraceToSingleLineString(ex)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Check connection of the provided replication domain to the provided |
| | | * replication server. Waits for connection to be ok up to secTimeout seconds |
| | | * before failing. |
| | | */ |
| | | private void checkConnection(int secTimeout, int dsId, int rsId) |
| | | throws Exception |
| | | { |
| | | int rsPort = -1; |
| | | LDAPReplicationDomain rd = null; |
| | |
| | | if (connected) |
| | | { |
| | | String serverStr = rd.getReplicationServer(); |
| | | int index = serverStr.lastIndexOf(':'); |
| | | if ((index == -1) || (index >= serverStr.length())) |
| | | fail("Enable to find port number in: " + serverStr); |
| | | String rdPortStr = serverStr.substring(index + 1); |
| | | try |
| | | { |
| | | rdPort = (new Integer(rdPortStr)).intValue(); |
| | | } catch (Exception e) |
| | | { |
| | | fail("Enable to get an int from: " + rdPortStr); |
| | | } |
| | | rdPort = HostPort.valueOf(serverStr).getPort(); |
| | | if (rdPort == rsPort) |
| | | rightPort = true; |
| | | } |
| | |
| | | } |
| | | |
| | | // Sleep 1 second |
| | | try |
| | | { |
| | | Thread.sleep(1000); |
| | | } catch (InterruptedException ex) |
| | | { |
| | | fail("Error sleeping " + stackTraceToSingleLineString(ex)); |
| | | } |
| | | nSec++; |
| | | |
| | | if (nSec > secTimeout) |
| | |
| | | * Creates a new ReplicationServer. |
| | | */ |
| | | private ReplicationServer createReplicationServer(int rsId, String testCase) |
| | | { |
| | | try |
| | | throws ConfigException |
| | | { |
| | | SortedSet<String> replServers = createRSListExceptOne(rsId); |
| | | |
| | |
| | | ReplServerFakeConfiguration conf = |
| | | new ReplServerFakeConfiguration(rsPort, dir, 0, rsId, 0, 100, |
| | | replServers, groupId, 1000, 5000); |
| | | ReplicationServer replicationServer = new ReplicationServer(conf); |
| | | return replicationServer; |
| | | |
| | | } catch (Exception e) |
| | | { |
| | | fail("createReplicationServer " + stackTraceToSingleLineString(e)); |
| | | } |
| | | return null; |
| | | return new ReplicationServer(conf); |
| | | } |
| | | |
| | | /** |
| | |
| | | * know RSs according to DS id |
| | | */ |
| | | private LDAPReplicationDomain createReplicationDomain(int dsId) |
| | | { |
| | | try |
| | | throws Exception |
| | | { |
| | | SortedSet<String> replServers = new TreeSet<String>(); |
| | | int groupId = -1; |
| | |
| | | replicationDomain.start(); |
| | | |
| | | return replicationDomain; |
| | | |
| | | } catch (Exception e) |
| | | { |
| | | fail("createReplicationDomain " + stackTraceToSingleLineString(e)); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | // Definitions of steps for the test case |
| | |
| | | */ |
| | | debugInfo("*** STEP 2 ***"); |
| | | rd2 = createReplicationDomain(DS2_ID); |
| | | sleep(500); // Let time to topo msgs being propagated through the network |
| | | Thread.sleep(500); // Let time to topo msgs being propagated through the network |
| | | checkConnection(30, DS1_ID, RS1_ID); |
| | | checkConnection(30, DS2_ID, RS1_ID); |
| | | theoricalTopoView = createTheoreticalTopoViewForStep(STEP_2); |
| | |
| | | */ |
| | | debugInfo("*** STEP 3 ***"); |
| | | rs2 = createReplicationServer(RS2_ID, testCase); |
| | | sleep(1000); // Let time to topo msgs being propagated through the network |
| | | Thread.sleep(1000); // Let time to topo msgs being propagated through the network |
| | | checkConnection(30, DS1_ID, RS1_ID); |
| | | checkConnection(30, DS2_ID, RS1_ID); |
| | | theoricalTopoView = createTheoreticalTopoViewForStep(STEP_3); |
| | |
| | | */ |
| | | debugInfo("*** STEP 4 ***"); |
| | | rd3 = createReplicationDomain(DS3_ID); |
| | | sleep(500); // Let time to topo msgs being propagated through the network |
| | | Thread.sleep(500); // Let time to topo msgs being propagated through the network |
| | | checkConnection(30, DS1_ID, RS1_ID); |
| | | checkConnection(30, DS2_ID, RS1_ID); |
| | | checkConnection(30, DS3_ID, RS2_ID); |
| | |
| | | */ |
| | | debugInfo("*** STEP 5 ***"); |
| | | rd4 = createReplicationDomain(DS4_ID); |
| | | sleep(500); // Let time to topo msgs being propagated through the network |
| | | Thread.sleep(500); // Let time to topo msgs being propagated through the network |
| | | checkConnection(30, DS1_ID, RS1_ID); |
| | | checkConnection(30, DS2_ID, RS1_ID); |
| | | checkConnection(30, DS3_ID, RS2_ID); |
| | |
| | | */ |
| | | debugInfo("*** STEP 6 ***"); |
| | | rd5 = createReplicationDomain(DS5_ID); |
| | | sleep(500); // Let time to topo msgs being propagated through the network |
| | | Thread.sleep(500); // Let time to topo msgs being propagated through the network |
| | | checkConnection(30, DS1_ID, RS1_ID); |
| | | checkConnection(30, DS2_ID, RS1_ID); |
| | | checkConnection(30, DS3_ID, RS2_ID); |
| | |
| | | */ |
| | | debugInfo("*** STEP 7 ***"); |
| | | rs3 = createReplicationServer(RS3_ID, testCase); |
| | | sleep(500); // Let time to topo msgs being propagated through the network |
| | | Thread.sleep(500); // Let time to topo msgs being propagated through the network |
| | | checkConnection(30, DS1_ID, RS1_ID); |
| | | checkConnection(30, DS2_ID, RS1_ID); |
| | | checkConnection(30, DS3_ID, RS2_ID); |
| | |
| | | */ |
| | | debugInfo("*** STEP 8 ***"); |
| | | rd6 = createReplicationDomain(DS6_ID); |
| | | sleep(500); // Let time to topo msgs being propagated through the network |
| | | Thread.sleep(500); // Let time to topo msgs being propagated through the network |
| | | checkConnection(30, DS1_ID, RS1_ID); |
| | | checkConnection(30, DS2_ID, RS1_ID); |
| | | checkConnection(30, DS3_ID, RS2_ID); |
| | |
| | | */ |
| | | debugInfo("*** STEP 9 ***"); |
| | | rd6.disable(); |
| | | sleep(500); // Let time to topo msgs being propagated through the network |
| | | Thread.sleep(500); // Let time to topo msgs being propagated through the network |
| | | checkConnection(30, DS1_ID, RS1_ID); |
| | | checkConnection(30, DS2_ID, RS1_ID); |
| | | checkConnection(30, DS3_ID, RS2_ID); |
| | |
| | | */ |
| | | debugInfo("*** STEP 10 ***"); |
| | | rd6.enable(); |
| | | sleep(500); // Let time to topo msgs being propagated through the network |
| | | Thread.sleep(500); // Let time to topo msgs being propagated through the network |
| | | checkConnection(30, DS1_ID, RS1_ID); |
| | | checkConnection(30, DS2_ID, RS1_ID); |
| | | checkConnection(30, DS3_ID, RS2_ID); |
| | |
| | | */ |
| | | debugInfo("*** STEP 11 ***"); |
| | | rs3.remove(); |
| | | sleep(500); // Let time to topo msgs being propagated through the network |
| | | Thread.sleep(500); // Let time to topo msgs being propagated through the network |
| | | checkConnection(30, DS1_ID, RS1_ID); |
| | | checkConnection(30, DS2_ID, RS1_ID); |
| | | checkConnection(30, DS3_ID, RS2_ID); |
| | |
| | | */ |
| | | debugInfo("*** STEP 12 ***"); |
| | | rs3 = createReplicationServer(RS3_ID, testCase); |
| | | sleep(500); // Let time to topo msgs being propagated through the network |
| | | Thread.sleep(500); // Let time to topo msgs being propagated through the network |
| | | checkConnection(30, DS1_ID, RS1_ID); |
| | | checkConnection(30, DS2_ID, RS1_ID); |
| | | checkConnection(30, DS3_ID, RS2_ID); |
| | |
| | | */ |
| | | debugInfo("*** STEP 13 ***"); |
| | | rs2.remove(); |
| | | sleep(500); // Let time to topo msgs being propagated through the network |
| | | Thread.sleep(500); // Let time to topo msgs being propagated through the network |
| | | checkConnection(30, DS1_ID, RS1_ID); |
| | | checkConnection(30, DS2_ID, RS1_ID); |
| | | checkConnection(30, DS5_ID, RS3_ID); |
| | |
| | | * this method is called. |
| | | */ |
| | | private void checkTopoView(int[] dsIdList, TopoView theoricalTopoView) |
| | | throws Exception |
| | | { |
| | | sleep(500); |
| | | Thread.sleep(500); |
| | | for(int currentDsId : dsIdList) |
| | | { |
| | | LDAPReplicationDomain rd = null; |
| | |
| | | */ |
| | | package org.opends.server.replication.server; |
| | | |
| | | import static org.opends.server.TestCaseUtils.*; |
| | | import static org.opends.server.loggers.ErrorLogger.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.testng.Assert.*; |
| | | |
| | | import java.io.File; |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | |
| | | import org.opends.server.replication.service.ReplicationDomain; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.HostPort; |
| | | import org.opends.server.util.StaticUtils; |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.DataProvider; |
| | | import org.testng.annotations.Test; |
| | | |
| | | import static org.opends.server.TestCaseUtils.*; |
| | | import static org.opends.server.loggers.ErrorLogger.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.testng.Assert.*; |
| | | |
| | | /** |
| | | * Test Server part of the assured feature in both safe data and |
| | | * safe read modes. |
| | |
| | | // Test connection |
| | | assertTrue(fakeReplicationDomain.isConnected()); |
| | | // Check connected server port |
| | | String serverStr = fakeReplicationDomain.getReplicationServer(); |
| | | int index = serverStr.lastIndexOf(':'); |
| | | assertFalse(index == -1, "Enable to find port number in: " + serverStr); |
| | | String rdPortStr = serverStr.substring(index + 1); |
| | | int rdPort = Integer.parseInt(rdPortStr);// fail the test if not an int |
| | | assertEquals(rdPort, rsPort); |
| | | HostPort rd = |
| | | HostPort.valueOf(fakeReplicationDomain.getReplicationServer()); |
| | | assertEquals(rd.getPort(), rsPort); |
| | | |
| | | return fakeReplicationDomain; |
| | | } |
| | |
| | | AckMsg ackMsg = new AckMsg(updateMsg.getCSN()); |
| | | ackMsg.setHasWrongStatus(true); |
| | | List<Integer> failedServers = new ArrayList<Integer>(); |
| | | failedServers.add((serverId + 10)); |
| | | failedServers.add(serverId + 10); |
| | | ackMsg.setFailedServers(failedServers); |
| | | session.publish(ackMsg); |
| | | ackReplied = true; |
| | |
| | | AckMsg ackMsg = new AckMsg(updateMsg.getCSN()); |
| | | ackMsg.setHasReplayError(true); |
| | | List<Integer> failedServers = new ArrayList<Integer>(); |
| | | failedServers.add((serverId + 10)); |
| | | failedServers.add(serverId + 10); |
| | | ackMsg.setFailedServers(failedServers); |
| | | session.publish(ackMsg); |
| | | ackReplied = true; |
| | |
| | | } |
| | | |
| | | /** |
| | | * Sleep a while |
| | | */ |
| | | private void sleep(long time) |
| | | { |
| | | try |
| | | { |
| | | Thread.sleep(time); |
| | | } catch (InterruptedException ex) |
| | | { |
| | | fail("Error sleeping " + ex); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * See testSafeDataLevelOne comment. |
| | | * This is a facility to run the testSafeDataLevelOne in precommit in simplest |
| | | * case, so that precommit run test something and is not long. |
| | |
| | | long sendUpdateTime = System.currentTimeMillis() - startTime; |
| | | assertTrue(sendUpdateTime < MAX_SEND_UPDATE_TIME); |
| | | |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | if (mainDsGid == DEFAULT_GID) |
| | | { |
| | | // Check monitoring values (check that ack has been correctly received) |
| | |
| | | } |
| | | |
| | | // Sanity check |
| | | sleep(500); // Let time to update to reach other servers |
| | | Thread.sleep(500); // Let time to update to reach other servers |
| | | assertEquals(fakeRd1.getReceivedUpdates(), 0); |
| | | assertTrue(fakeRd1.receivedUpdatesOk()); |
| | | if (otherFakeDS) |
| | |
| | | long sendUpdateTime = System.currentTimeMillis() - startTime; |
| | | |
| | | // Check |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked and let time the update to reach other servers |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked and let time the update to reach other servers |
| | | checkTimeAndMonitoringSafeData(1, acknowledgedUpdates, timeoutUpdates, serverErrors, sendUpdateTime, nWishedServers, eligibleServers, expectedServers); |
| | | checkWhatHasBeenReceivedSafeData(1, otherFakeDS, otherFakeDsGenId, fakeRs1GenId, fakeRs2GenId, fakeRs3GenId, expectedServers); |
| | | |
| | |
| | | sendUpdateTime = System.currentTimeMillis() - startTime; |
| | | |
| | | // Check |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked and let time the update to reach other servers |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked and let time the update to reach other servers |
| | | checkTimeAndMonitoringSafeData(2, acknowledgedUpdates, timeoutUpdates, serverErrors, sendUpdateTime, nWishedServers, eligibleServers, expectedServers); |
| | | checkWhatHasBeenReceivedSafeData(2, otherFakeDS, otherFakeDsGenId, fakeRs1GenId, fakeRs2GenId, -1L, expectedServers); |
| | | |
| | |
| | | sendUpdateTime = System.currentTimeMillis() - startTime; |
| | | |
| | | // Check |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked and let time the update to reach other servers |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked and let time the update to reach other servers |
| | | checkTimeAndMonitoringSafeData(3, acknowledgedUpdates, timeoutUpdates, serverErrors, sendUpdateTime, nWishedServers, eligibleServers, expectedServers); |
| | | checkWhatHasBeenReceivedSafeData(3, otherFakeDS, otherFakeDsGenId, fakeRs1GenId, -1L, -1L, expectedServers); |
| | | |
| | |
| | | sendUpdateTime = System.currentTimeMillis() - startTime; |
| | | |
| | | // Check |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked and let time the update to reach other servers |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked and let time the update to reach other servers |
| | | checkTimeAndMonitoringSafeData(4, acknowledgedUpdates, timeoutUpdates, serverErrors, sendUpdateTime, nWishedServers, eligibleServers, expectedServers); |
| | | checkWhatHasBeenReceivedSafeData(4, otherFakeDS, otherFakeDsGenId, -1L, -1L, -1L, expectedServers); |
| | | } finally |
| | |
| | | * Wait until number of fake DSs and fake RSs are available in the topo view of the passed |
| | | * fake DS or throw an assertion if timeout waiting. |
| | | */ |
| | | private void waitForStableTopo(FakeReplicationDomain fakeRd, int expectedDs, int expectedRs) |
| | | private void waitForStableTopo(FakeReplicationDomain fakeRd, int expectedDs, |
| | | int expectedRs) throws Exception |
| | | { |
| | | List<DSInfo> dsInfo = null; |
| | | List<RSInfo> rsInfo = null; |
| | |
| | | debugInfo("waitForStableTopo: expected topo obtained after " + nSec + " second(s)."); |
| | | return; |
| | | } |
| | | sleep(100); |
| | | Thread.sleep(100); |
| | | nSec = (System.currentTimeMillis() - startTime) / 1000; |
| | | } |
| | | while (nSec < 30); |
| | |
| | | assertTrue(sendUpdateTime < MAX_SEND_UPDATE_TIME); |
| | | |
| | | // Check monitoring values (check that ack has been correctly received) |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | assertEquals(fakeRd1.getAssuredSdSentUpdates(), 1); |
| | | assertEquals(fakeRd1.getAssuredSdAcknowledgedUpdates(), 1); |
| | | assertEquals(fakeRd1.getAssuredSdTimeoutUpdates(), 0); |
| | |
| | | assertTrue(sendUpdateTime < MAX_SEND_UPDATE_TIME); |
| | | |
| | | // Check monitoring values (check that ack has been correctly received) |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | assertEquals(fakeRd1.getAssuredSrSentUpdates(), 1); |
| | | assertEquals(fakeRd1.getAssuredSrAcknowledgedUpdates(), 1); |
| | | assertEquals(fakeRd1.getAssuredSrNotAcknowledgedUpdates(), 0); |
| | |
| | | assertTrue(sendUpdateTime < MAX_SEND_UPDATE_TIME); |
| | | |
| | | // Check monitoring values (check that ack has been correctly received) |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | assertEquals(fakeRd1.getAssuredSrSentUpdates(), 2); |
| | | assertEquals(fakeRd1.getAssuredSrAcknowledgedUpdates(), 2); |
| | | assertEquals(fakeRd1.getAssuredSrNotAcknowledgedUpdates(), 0); |
| | |
| | | assertTrue(sendUpdateTime < MAX_SEND_UPDATE_TIME); |
| | | |
| | | // Check monitoring values (check that ack has been correctly received) |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | assertEquals(fakeRd1.getAssuredSrSentUpdates(), 3); |
| | | assertEquals(fakeRd1.getAssuredSrAcknowledgedUpdates(), 3); |
| | | assertEquals(fakeRd1.getAssuredSrNotAcknowledgedUpdates(), 0); |
| | |
| | | assertTrue(sendUpdateTime < MAX_SEND_UPDATE_TIME); |
| | | |
| | | // Check monitoring values (check that ack has been correctly received) |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | assertEquals(fakeRd1.getAssuredSrSentUpdates(), 4); |
| | | assertEquals(fakeRd1.getAssuredSrAcknowledgedUpdates(), 4); |
| | | assertEquals(fakeRd1.getAssuredSrNotAcknowledgedUpdates(), 0); |
| | |
| | | assertTrue(sendUpdateTime < MAX_SEND_UPDATE_TIME); |
| | | |
| | | // Check monitoring values (check that ack has been correctly received) |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | assertEquals(fakeRd1.getAssuredSrSentUpdates(), 5); |
| | | assertEquals(fakeRd1.getAssuredSrAcknowledgedUpdates(), 5); |
| | | assertEquals(fakeRd1.getAssuredSrNotAcknowledgedUpdates(), 0); |
| | |
| | | } |
| | | |
| | | // Sleep a while as counters are updated just after sending thread is unblocked |
| | | sleep(500); |
| | | Thread.sleep(500); |
| | | |
| | | // Check monitoring values in DS 1 |
| | | // |
| | |
| | | assertTrue(sendUpdateTime < MAX_SEND_UPDATE_TIME); |
| | | |
| | | // Check monitoring values (check that ack has been correctly received) |
| | | sleep(1000); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(1000); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | |
| | | checkDSSentAndAcked(fakeRd1, 1); |
| | | |
| | |
| | | assertTrue(sendUpdateTime < MAX_SEND_UPDATE_TIME, "Exceeded max send time: " + sendUpdateTime); |
| | | |
| | | // Check monitoring values (check that ack has been correctly received) |
| | | sleep(1000); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(1000); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | |
| | | checkDSSentAndAcked(fakeRd1, 2); |
| | | |
| | |
| | | assertTrue(sendUpdateTime < MAX_SEND_UPDATE_TIME); |
| | | |
| | | // Check monitoring values (check that ack has been correctly received) |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | |
| | | checkDSSentAndAcked(fakeRd1, 1); |
| | | |
| | |
| | | assertTrue(sendUpdateTime < MAX_SEND_UPDATE_TIME); |
| | | |
| | | // Check monitoring values (check that ack has been correctly received) |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | |
| | | if (fakeDsIsEligible) |
| | | { |
| | |
| | | } |
| | | else |
| | | { |
| | | sleep(1000); |
| | | Thread.sleep(1000); |
| | | } |
| | | } |
| | | assertFalse(error, "DS2 not in degraded status"); |
| | | |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | assertEquals(fakeRd1.getAssuredSrSentUpdates(), 4); |
| | | assertEquals(fakeRd1.getAssuredSrAcknowledgedUpdates(), 0); |
| | | assertEquals(fakeRd1.getAssuredSrNotAcknowledgedUpdates(), 4); |
| | |
| | | // RS should ack quickly as DS2 degraded and not eligible for assured |
| | | assertTrue(sendUpdateTime < MAX_SEND_UPDATE_TIME); |
| | | |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | assertEquals(fakeRd1.getAssuredSrSentUpdates(), 5); |
| | | assertEquals(fakeRd1.getAssuredSrAcknowledgedUpdates(), 1); |
| | | assertEquals(fakeRd1.getAssuredSrNotAcknowledgedUpdates(), 4); |
| | |
| | | } |
| | | else |
| | | { |
| | | sleep(1000); |
| | | Thread.sleep(1000); |
| | | } |
| | | } |
| | | assertFalse(error, "DS2 not back to normal status"); |
| | |
| | | // RS should ack quickly as DS2 degraded and not eligible for assured |
| | | assertTrue(sendUpdateTime < MAX_SEND_UPDATE_TIME); |
| | | |
| | | sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | Thread.sleep(500); // Sleep a while as counters are updated just after sending thread is unblocked |
| | | assertEquals(fakeRd1.getAssuredSrSentUpdates(), 6); |
| | | assertEquals(fakeRd1.getAssuredSrAcknowledgedUpdates(), 2); |
| | | assertEquals(fakeRd1.getAssuredSrNotAcknowledgedUpdates(), 4); |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2013 ForgeRock AS |
| | | */ |
| | | package org.opends.server.types; |
| | | |
| | | import org.testng.annotations.Test; |
| | | |
| | | import static org.assertj.core.api.Assertions.*; |
| | | |
| | | @Test(groups = { "precommit", "types" }) |
| | | @SuppressWarnings("javadoc") |
| | | public class HostPortTest extends TypesTestCase |
| | | { |
| | | |
| | | public void valueOfIPv4NoSpaces() |
| | | { |
| | | final String serverURL = "home:1"; |
| | | final HostPort hp = HostPort.valueOf(serverURL); |
| | | assertThat(hp.getHost()).isEqualTo("home"); |
| | | assertThat(hp.getPort()).isEqualTo(1); |
| | | assertThat(hp.toString()).isEqualTo(serverURL); |
| | | } |
| | | |
| | | public void valueOfIPv4Spaces() |
| | | { |
| | | final String serverURL = "home:1"; |
| | | final HostPort hp = HostPort.valueOf(" " + serverURL + " "); |
| | | assertThat(hp.getHost()).isEqualTo("home"); |
| | | assertThat(hp.getPort()).isEqualTo(1); |
| | | assertThat(hp.toString()).isEqualTo(serverURL); |
| | | } |
| | | |
| | | public void valueOfEqualsHashCodeIPv4() |
| | | { |
| | | final HostPort hp1 = HostPort.valueOf("home:1"); |
| | | final HostPort hp2 = HostPort.valueOf(" home:1 "); |
| | | assertThat(hp1).isEqualTo(hp2); |
| | | assertThat(hp1.hashCode()).isEqualTo(hp2.hashCode()); |
| | | } |
| | | |
| | | public void valueOfIPv6Brackets() |
| | | { |
| | | final String hostName = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"; |
| | | final String serverURL = "[" + hostName + "]:389"; |
| | | final HostPort hp = HostPort.valueOf(serverURL); |
| | | assertThat(hp.getHost()).isEqualTo(hostName); |
| | | assertThat(hp.getPort()).isEqualTo(389); |
| | | assertThat(hp.toString()).isEqualTo(serverURL); |
| | | } |
| | | |
| | | public void valueOfIPv6NoBrackets() |
| | | { |
| | | final String hostName = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"; |
| | | final HostPort hp = HostPort.valueOf(hostName + ":389"); |
| | | assertThat(hp.getHost()).isEqualTo(hostName); |
| | | assertThat(hp.getPort()).isEqualTo(389); |
| | | assertThat(hp.toString()).isEqualTo("[" + hostName + "]:389"); |
| | | } |
| | | |
| | | public void valueOfEqualsHashCodeIPv6() |
| | | { |
| | | final String hostName = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"; |
| | | final HostPort hp1 = HostPort.valueOf("[" + hostName + "]:389"); |
| | | final HostPort hp2 = HostPort.valueOf(" " + hostName + " : 389 "); |
| | | assertThat(hp1).isEqualTo(hp2); |
| | | assertThat(hp1.hashCode()).isEqualTo(hp2.hashCode()); |
| | | } |
| | | |
| | | @Test(expectedExceptions = IllegalArgumentException.class) |
| | | public void valueOfNoPort() |
| | | { |
| | | HostPort.valueOf("host"); |
| | | } |
| | | |
| | | @Test(expectedExceptions = IllegalArgumentException.class) |
| | | public void valueOfNoHost() |
| | | { |
| | | HostPort.valueOf(":389"); |
| | | } |
| | | |
| | | @Test(expectedExceptions = NumberFormatException.class) |
| | | public void valueOfPortNotANumber() |
| | | { |
| | | HostPort.valueOf("host:port"); |
| | | } |
| | | |
| | | @Test(expectedExceptions = IllegalArgumentException.class) |
| | | public void valueOfPortNumberTooSmall() |
| | | { |
| | | HostPort.valueOf("host:-1"); |
| | | } |
| | | |
| | | @Test(expectedExceptions = IllegalArgumentException.class) |
| | | public void valueOfPortNumberTooBig() |
| | | { |
| | | HostPort.valueOf("host:99999999"); |
| | | } |
| | | |
| | | } |