| | |
| | | import javax.naming.NameNotFoundException; |
| | | import javax.naming.NamingEnumeration; |
| | | import javax.naming.NamingException; |
| | | import javax.naming.NoPermissionException; |
| | | import javax.naming.directory.BasicAttributes; |
| | | import javax.naming.directory.DirContext; |
| | | import javax.naming.directory.SearchControls; |
| | | import javax.naming.directory.SearchResult; |
| | | import javax.naming.ldap.InitialLdapContext; |
| | | import javax.naming.ldap.LdapName; |
| | | import javax.net.ssl.KeyManager; |
| | | import javax.net.ssl.SSLException; |
| | |
| | | private boolean forceNonInteractive; |
| | | |
| | | /** Always use SSL with the administration connector. */ |
| | | private final Type connectiontype = LDAPS; |
| | | private final Type connectionType = LDAPS; |
| | | |
| | | /** |
| | | * The enumeration containing the different options we display when we ask |
| | |
| | | * @param interactive if user has to input information |
| | | * @return whether we should stop |
| | | */ |
| | | boolean continueAfterUserInput(Collection<String> baseDNs, InitialLdapContext source, InitialLdapContext dest, |
| | | boolean continueAfterUserInput(Collection<String> baseDNs, ConnectionWrapper source, ConnectionWrapper dest, |
| | | boolean interactive); |
| | | |
| | | /** |
| | | * Confirm with the user whether the current task should continue. |
| | | * |
| | | * @param uData servers address and authentication parameters |
| | | * @param ctxSource LDAP Context for the destination server |
| | | * @param ctxDestination LDAP Context for the source server |
| | | * @param connSource connection to the source server |
| | | * @param connDestination connection to the destination server |
| | | * @param defaultValue default yes or no |
| | | * @return whether the current task should be interrupted |
| | | */ |
| | | boolean confirmOperation(SourceDestinationServerUserData uData, InitialLdapContext ctxSource, |
| | | InitialLdapContext ctxDestination, final boolean defaultValue); |
| | | boolean confirmOperation(SourceDestinationServerUserData uData, ConnectionWrapper connSource, |
| | | ConnectionWrapper connDestination, final boolean defaultValue); |
| | | } |
| | | |
| | | /** The argument parser to be used. */ |
| | |
| | | return returnCode; |
| | | } |
| | | |
| | | /** |
| | | * Returns an InitialLdapContext using the provided parameters. We try to |
| | | * guarantee that the connection is able to read the configuration. |
| | | * |
| | | * @param hostPort |
| | | * the host name and port to connect. |
| | | * @param useSSL |
| | | * whether to use SSL or not. |
| | | * @param useStartTLS |
| | | * whether to use StartTLS or not. |
| | | * @param bindDn |
| | | * the bind dn to be used. |
| | | * @param pwd |
| | | * the password. |
| | | * @param connectTimeout |
| | | * the timeout in milliseconds to connect to the server. |
| | | * @param trustManager |
| | | * the trust manager. |
| | | * @return an InitialLdapContext connected. |
| | | * @throws NamingException |
| | | * if there was an error establishing the connection. |
| | | */ |
| | | private static InitialLdapContext createAdministrativeContext(HostPort hostPort, |
| | | boolean useSSL, boolean useStartTLS, String bindDn, String pwd, |
| | | int connectTimeout, ApplicationTrustManager trustManager) |
| | | throws NamingException |
| | | { |
| | | InitialLdapContext ctx; |
| | | String ldapUrl = getLDAPUrl(hostPort, useSSL); |
| | | if (useSSL) |
| | | { |
| | | ctx = createLdapsContext(ldapUrl, bindDn, pwd, connectTimeout, null, trustManager, null); |
| | | } |
| | | else if (useStartTLS) |
| | | { |
| | | ctx = createStartTLSContext(ldapUrl, bindDn, pwd, connectTimeout, null, trustManager, null); |
| | | } |
| | | else |
| | | { |
| | | ctx = createLdapContext(ldapUrl, bindDn, pwd, connectTimeout, null); |
| | | } |
| | | if (!connectedAsAdministrativeUser(ctx)) |
| | | { |
| | | throw new NoPermissionException(ERR_NOT_ADMINISTRATIVE_USER.get().toString()); |
| | | } |
| | | return ctx; |
| | | } |
| | | |
| | | private ConnectionWrapper createConnectionInteracting(LDAPConnectionConsoleInteraction ci) |
| | | throws ClientException |
| | | private ConnectionWrapper createConnectionInteracting(LDAPConnectionConsoleInteraction ci) throws ClientException |
| | | { |
| | | return createConnectionInteracting(ci, isInteractive() && ci.isTrustStoreInMemory()); |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * Creates an Initial LDAP Context interacting with the user if the |
| | | * application is interactive. |
| | | * Creates a connection interacting with the user if the application is interactive. |
| | | * |
| | | * @param ci |
| | | * the LDAPConnectionConsoleInteraction object that is assumed to |
| | | * have been already run. |
| | | * the LDAPConnectionConsoleInteraction object that is assumed to have been already run. |
| | | * @param promptForCertificate |
| | | * whether we should prompt for the certificate or not. |
| | | * @return the initial LDAP context or <CODE>null</CODE> if the user did not |
| | | * accept to trust the certificates. |
| | | * @return the connection or {@code null} if the user did not accept to trust the certificates. |
| | | * @throws ClientException |
| | | * if there was an error establishing the connection. |
| | | */ |
| | |
| | | return new ClientException(ReturnCode.CLIENT_SIDE_CONNECT_ERROR, ERR_FAILED_TO_CONNECT.get(hostName, portNumber)); |
| | | } |
| | | |
| | | private ReplicationCliReturnCode purgeHistoricalRemotely( |
| | | PurgeHistoricalUserData uData) |
| | | private ReplicationCliReturnCode purgeHistoricalRemotely(PurgeHistoricalUserData uData) |
| | | { |
| | | InitialLdapContext ctx = createAdministrativeContext(uData); |
| | | if (ctx == null) |
| | | ConnectionWrapper conn = createAdministrativeConnection(uData); |
| | | if (conn == null) |
| | | { |
| | | return ERROR_CONNECTING; |
| | | } |
| | |
| | | try |
| | | { |
| | | List<String> baseDNs = uData.getBaseDNs(); |
| | | checkSuffixesForPurgeHistorical(baseDNs, ctx, false); |
| | | checkSuffixesForPurgeHistorical(baseDNs, conn, false); |
| | | if (baseDNs.isEmpty()) |
| | | { |
| | | return HISTORICAL_CANNOT_BE_PURGED_ON_BASEDN; |
| | |
| | | |
| | | try |
| | | { |
| | | return purgeHistoricalRemoteTask(ctx, uData); |
| | | return purgeHistoricalRemoteTask(conn, uData); |
| | | } |
| | | catch (ReplicationCliException rce) |
| | | { |
| | |
| | | } |
| | | finally |
| | | { |
| | | close(ctx); |
| | | close(conn); |
| | | } |
| | | } |
| | | |
| | |
| | | resetChangeNumberOperations = new OperationBetweenSourceAndDestinationServers() |
| | | { |
| | | @Override |
| | | public boolean continueAfterUserInput(Collection<String> baseDNs, InitialLdapContext source, |
| | | InitialLdapContext dest, boolean interactive) |
| | | public boolean continueAfterUserInput(Collection<String> baseDNs, ConnectionWrapper source, |
| | | ConnectionWrapper dest, boolean interactive) |
| | | { |
| | | TopologyCacheFilter filter = new TopologyCacheFilter(); |
| | | filter.setSearchMonitoringInformation(false); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public boolean confirmOperation(SourceDestinationServerUserData uData, InitialLdapContext ctxSource, |
| | | InitialLdapContext ctxDestination, boolean defaultValue) |
| | | public boolean confirmOperation(SourceDestinationServerUserData uData, ConnectionWrapper connSource, |
| | | ConnectionWrapper connDestination, boolean defaultValue) |
| | | { |
| | | return !askConfirmation(INFO_RESET_CHANGE_NUMBER_CONFIRM_RESET.get(uData.getDestinationHostPort()), |
| | | defaultValue); |
| | |
| | | |
| | | private ReplicationCliReturnCode resetChangeNumber(SourceDestinationServerUserData uData) |
| | | { |
| | | |
| | | InitialLdapContext ctxSource = createAdministrativeContext(uData, uData.getSource()); |
| | | InitialLdapContext ctxDest = createAdministrativeContext(uData, uData.getDestination()); |
| | | if (!getCommonSuffixes(ctxSource, ctxDest, SuffixRelationType.NOT_FULLY_REPLICATED).isEmpty()) |
| | | ConnectionWrapper connSource = createAdministrativeConnection(uData, uData.getSource()); |
| | | ConnectionWrapper connDest = createAdministrativeConnection(uData, uData.getDestination()); |
| | | if (!getCommonSuffixes(connSource, connDest, SuffixRelationType.NOT_FULLY_REPLICATED).isEmpty()) |
| | | { |
| | | errPrintln(ERROR_RESET_CHANGE_NUMBER_SERVERS_BASEDNS_DIFFER.get(uData.getSourceHostPort(), |
| | | uData.getDestinationHostPort())); |
| | |
| | | } |
| | | else |
| | | { |
| | | newStartCN = getNewestChangeNumber(ctxSource); |
| | | newStartCN = getNewestChangeNumber(connSource); |
| | | if (newStartCN.isEmpty()) |
| | | { |
| | | return ERROR_UNKNOWN_CHANGE_NUMBER; |
| | |
| | | "replicationCSN", |
| | | "targetDN" |
| | | }); |
| | | NamingEnumeration<SearchResult> listeners = ctxSource.search(new LdapName("cn=changelog"), |
| | | "(changeNumber=" + newStartCN + ")", ctls); |
| | | NamingEnumeration<SearchResult> listeners = connSource.getLdapContext().search( |
| | | new LdapName("cn=changelog"), "(changeNumber=" + newStartCN + ")", ctls); |
| | | if (!listeners.hasMore()) |
| | | { |
| | | errPrintln(ERROR_RESET_CHANGE_NUMBER_UNKNOWN_NUMBER.get(newStartCN, uData.getSourceHostPort())); |
| | |
| | | DN targetBaseDN = DN.rootDN(); |
| | | try |
| | | { |
| | | for (String adn : getCommonSuffixes(ctxSource, ctxDest, SuffixRelationType.REPLICATED)) |
| | | for (String adn : getCommonSuffixes(connSource, connDest, SuffixRelationType.REPLICATED)) |
| | | { |
| | | DN dn = DN.valueOf(adn); |
| | | if (DN.valueOf(targetDN).isSubordinateOrEqualTo(dn) && dn.isSubordinateOrEqualTo(targetBaseDN)) |
| | |
| | | taskAttrs.put("ds-task-reset-change-number-to", newStartCN); |
| | | taskAttrs.put("ds-task-reset-change-number-csn", newStartCSN); |
| | | taskAttrs.put("ds-task-reset-change-number-base-dn", targetBaseDN.toString()); |
| | | String taskDN = createServerTask(ctxDest, |
| | | String taskDN = createServerTask(connDest, |
| | | "ds-task-reset-change-number", "org.opends.server.tasks.ResetChangeNumberTask", "dsreplication-reset-cn", |
| | | taskAttrs); |
| | | waitUntilResetChangeNumberTaskEnds(ctxDest, taskDN); |
| | | waitUntilResetChangeNumberTaskEnds(connDest, taskDN); |
| | | return SUCCESSFUL; |
| | | } |
| | | catch (ReplicationCliException | NamingException | NullPointerException e) |
| | |
| | | } |
| | | } |
| | | |
| | | private String getNewestChangeNumber(InitialLdapContext source) |
| | | private String getNewestChangeNumber(ConnectionWrapper conn) |
| | | { |
| | | try |
| | | { |
| | | SearchControls ctls = new SearchControls(); |
| | | ctls.setSearchScope(SearchControls.OBJECT_SCOPE); |
| | | ctls.setReturningAttributes(new String[] {"lastChangeNumber"}); |
| | | NamingEnumeration<SearchResult> results = source.search(new LdapName(""), "objectclass=*", ctls); |
| | | NamingEnumeration<SearchResult> results = conn.getLdapContext().search(new LdapName(""), "objectclass=*", ctls); |
| | | if (results.hasMore()) { |
| | | return getFirstValue(results.next(), "lastChangeNumber"); |
| | | } |
| | |
| | | return ""; |
| | | } |
| | | |
| | | private void waitUntilResetChangeNumberTaskEnds(InitialLdapContext server, String taskDN) |
| | | private void waitUntilResetChangeNumberTaskEnds(ConnectionWrapper conn, String taskDN) |
| | | throws ReplicationCliException |
| | | { |
| | | String lastLogMsg = null; |
| | |
| | | sleepCatchInterrupt(500); |
| | | try |
| | | { |
| | | SearchResult sr = getLastSearchResult(server, taskDN, "ds-task-log-message", "ds-task-state" ); |
| | | SearchResult sr = getLastSearchResult(conn, taskDN, "ds-task-log-message", "ds-task-state"); |
| | | String logMsg = getFirstValue(sr, "ds-task-log-message"); |
| | | if (logMsg != null && !logMsg.equals(lastLogMsg)) |
| | | { |
| | |
| | | |
| | | if (helper.isDone(state) || helper.isStoppedByError(state)) |
| | | { |
| | | LocalizableMessage errorMsg = ERR_UNEXPECTED_DURING_TASK_WITH_LOG.get(lastLogMsg, state, server); |
| | | |
| | | LocalizableMessage errorMsg = ERR_UNEXPECTED_DURING_TASK_WITH_LOG.get(lastLogMsg, state, conn.getHostPort()); |
| | | if (helper.isCompletedWithErrors(state)) |
| | | { |
| | | logger.warn(LocalizableMessage.raw("Completed with error: " + errorMsg)); |
| | |
| | | } |
| | | } |
| | | |
| | | private InitialLdapContext createAdministrativeContext(MonoServerReplicationUserData uData) |
| | | { |
| | | final String bindDn = getAdministratorDN(uData.getAdminUid()); |
| | | return createAdministrativeContext(uData, bindDn); |
| | | } |
| | | |
| | | private ConnectionWrapper createAdministrativeConnection(MonoServerReplicationUserData uData) |
| | | { |
| | | final String bindDn = getAdministratorDN(uData.getAdminUid()); |
| | | return createAdministrativeConnection(uData, bindDn); |
| | | return createAdministrativeConnection(uData, getAdministratorDN(uData.getAdminUid())); |
| | | } |
| | | |
| | | private ConnectionWrapper createAdministrativeConnection(MonoServerReplicationUserData uData, final String bindDn) |
| | | { |
| | | try |
| | | { |
| | | return new ConnectionWrapper(uData.getHostPort(), connectiontype, bindDn, uData.getAdminPwd(), |
| | | getConnectTimeout(), getTrustManager(sourceServerCI)); |
| | | return new ConnectionWrapper(uData.getHostPort(), connectionType, |
| | | bindDn, uData.getAdminPwd(), getConnectTimeout(), getTrustManager(sourceServerCI)); |
| | | } |
| | | catch (NamingException e) |
| | | { |
| | | errPrintln(); |
| | | errPrintln(getMessageForException(e, uData.getHostPort().toString())); |
| | | logger.error(LocalizableMessage.raw("Error when creating connection for:" + uData.getHostPort())); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private InitialLdapContext createAdministrativeContext(MonoServerReplicationUserData uData, final String bindDn) |
| | | { |
| | | try |
| | | { |
| | | boolean useStartTLS = START_TLS.equals(connectiontype); |
| | | boolean useSSL = LDAPS.equals(connectiontype); |
| | | return createAdministrativeContext(uData.getHostPort(), useSSL, useStartTLS, |
| | | bindDn, uData.getAdminPwd(), getConnectTimeout(), getTrustManager(sourceServerCI)); |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | | errPrintln(); |
| | | errPrintln(getMessageForException(ne, uData.getHostPort().toString())); |
| | | logger.error(LocalizableMessage.raw("Complete error stack:"), ne); |
| | | logger.error(LocalizableMessage.raw("Error when creating connection for:" + uData.getHostPort()), e); |
| | | return null; |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * Launches the purge historical operation using the |
| | | * provided connection. |
| | | * @param ctx the connection to the server. |
| | | * @throws ReplicationCliException if there is an error performing the |
| | | * operation. |
| | | * Launches the purge historical operation using the provided connection. |
| | | * |
| | | * @param conn |
| | | * the connection to the server. |
| | | * @throws ReplicationCliException |
| | | * if there is an error performing the operation. |
| | | */ |
| | | private ReplicationCliReturnCode purgeHistoricalRemoteTask( |
| | | InitialLdapContext ctx, |
| | | PurgeHistoricalUserData uData) |
| | | private ReplicationCliReturnCode purgeHistoricalRemoteTask(ConnectionWrapper conn, PurgeHistoricalUserData uData) |
| | | throws ReplicationCliException |
| | | { |
| | | printPurgeProgressMessage(uData); |
| | |
| | | taskID = PurgeHistoricalUserData.getTaskID(attrs); |
| | | try |
| | | { |
| | | DirContext dirCtx = ctx.createSubcontext(dn, attrs); |
| | | DirContext dirCtx = conn.getLdapContext().createSubcontext(dn, attrs); |
| | | taskCreated = true; |
| | | logger.info(LocalizableMessage.raw("created task entry: "+attrs)); |
| | | dirCtx.close(); |
| | |
| | | sleepCatchInterrupt(500); |
| | | try |
| | | { |
| | | SearchResult sr = getFirstSearchResult(ctx, dn, |
| | | SearchResult sr = getFirstSearchResult(conn, dn, |
| | | "ds-task-log-message", |
| | | "ds-task-state", |
| | | "ds-task-purge-conflicts-historical-purged-values-count", |
| | |
| | | if (helper.isDone(state) || helper.isStoppedByError(state)) |
| | | { |
| | | isOver = true; |
| | | LocalizableMessage errorMsg = getPurgeErrorMsg(lastLogMsg, state, ctx); |
| | | LocalizableMessage errorMsg = getPurgeErrorMsg(lastLogMsg, state, conn); |
| | | |
| | | if (helper.isCompletedWithErrors(state)) |
| | | { |
| | |
| | | return returnCode; |
| | | } |
| | | |
| | | private SearchResult getFirstSearchResult(InitialLdapContext ctx, String dn, String... returnedAttributes) |
| | | private SearchResult getFirstSearchResult(ConnectionWrapper conn, String dn, String... returnedAttributes) |
| | | throws NamingException |
| | | { |
| | | SearchControls searchControls = new SearchControls(); |
| | | searchControls.setCountLimit(1); |
| | | searchControls.setSearchScope(SearchControls.OBJECT_SCOPE); |
| | | searchControls.setReturningAttributes(returnedAttributes); |
| | | NamingEnumeration<SearchResult> res = ctx.search(dn, "objectclass=*", searchControls); |
| | | NamingEnumeration<SearchResult> res = conn.getLdapContext().search(dn, "objectclass=*", searchControls); |
| | | try |
| | | { |
| | | SearchResult sr = null; |
| | |
| | | } |
| | | } |
| | | |
| | | private LocalizableMessage getPurgeErrorMsg(String lastLogMsg, String state, InitialLdapContext ctx) |
| | | private LocalizableMessage getPurgeErrorMsg(String lastLogMsg, String state, ConnectionWrapper conn) |
| | | { |
| | | HostPort server = getHostPort(ctx); |
| | | HostPort hostPort = conn.getHostPort(); |
| | | if (lastLogMsg != null) |
| | | { |
| | | return ERR_UNEXPECTED_DURING_TASK_WITH_LOG.get(lastLogMsg, state, server); |
| | | return ERR_UNEXPECTED_DURING_TASK_WITH_LOG.get(lastLogMsg, state, hostPort); |
| | | } |
| | | return ERR_UNEXPECTED_DURING_TASK_NO_LOG.get(state, server); |
| | | return ERR_UNEXPECTED_DURING_TASK_NO_LOG.get(state, hostPort); |
| | | } |
| | | |
| | | /** |
| | |
| | | * for the server. |
| | | * @param suffixes the suffixes provided by the user. This Collection is |
| | | * updated with the base DNs that the user provided interactively. |
| | | * @param ctx connection to the server. |
| | | * @param conn connection to the server. |
| | | * @param interactive whether to ask the user to provide interactively |
| | | * base DNs if none of the provided base DNs can be purged. |
| | | */ |
| | | private void checkSuffixesForPurgeHistorical(Collection<String> suffixes, |
| | | InitialLdapContext ctx, boolean interactive) |
| | | private void checkSuffixesForPurgeHistorical(Collection<String> suffixes, ConnectionWrapper conn, boolean interactive) |
| | | { |
| | | checkSuffixesForPurgeHistorical(suffixes, getReplicas(ctx), interactive); |
| | | checkSuffixesForPurgeHistorical(suffixes, getReplicas(conn), interactive); |
| | | } |
| | | |
| | | /** |
| | |
| | | initializeReplicationOperations = new OperationBetweenSourceAndDestinationServers() |
| | | { |
| | | @Override |
| | | public boolean continueAfterUserInput(Collection<String> baseDNs, InitialLdapContext source, |
| | | InitialLdapContext dest, boolean interactive) |
| | | public boolean continueAfterUserInput(Collection<String> baseDNs, ConnectionWrapper source, |
| | | ConnectionWrapper dest, boolean interactive) |
| | | { |
| | | checkSuffixesForInitializeReplication(baseDNs, source, dest, interactive); |
| | | return baseDNs.isEmpty(); |
| | | } |
| | | |
| | | @Override |
| | | public boolean confirmOperation(SourceDestinationServerUserData uData, InitialLdapContext ctxSource, |
| | | InitialLdapContext ctxDestination, boolean defaultValue) |
| | | public boolean confirmOperation(SourceDestinationServerUserData uData, ConnectionWrapper connSource, |
| | | ConnectionWrapper connDestination, boolean defaultValue) |
| | | { |
| | | return !askConfirmation(getInitializeReplicationPrompt(uData, ctxSource, ctxDestination), defaultValue); |
| | | return !askConfirmation(getInitializeReplicationPrompt(uData, connSource, connDestination), defaultValue); |
| | | } |
| | | }; |
| | | return promptIfRequired(uData, initializeReplicationOperations) ? initializeReplication(uData) : USER_CANCELLED; |
| | |
| | | List<String> suffixes = argParser.getBaseDNs(); |
| | | if (uData.isOnline()) |
| | | { |
| | | checkSuffixesForPurgeHistorical(suffixes, connWrapper.getLdapContext(), true); |
| | | checkSuffixesForPurgeHistorical(suffixes, connWrapper, true); |
| | | } |
| | | else |
| | | { |
| | |
| | | |
| | | if (uData.isOnline()) |
| | | { |
| | | List<? extends TaskEntry> taskEntries = getAvailableTaskEntries(connWrapper.getLdapContext()); |
| | | List<? extends TaskEntry> taskEntries = getAvailableTaskEntries(connWrapper); |
| | | |
| | | TaskScheduleInteraction interaction = |
| | | new TaskScheduleInteraction(uData.getTaskSchedule(), argParser.taskArgs, this, |
| | |
| | | } |
| | | } |
| | | |
| | | private List<? extends TaskEntry> getAvailableTaskEntries( |
| | | InitialLdapContext ctx) |
| | | private List<? extends TaskEntry> getAvailableTaskEntries(ConnectionWrapper conn) |
| | | { |
| | | List<TaskEntry> taskEntries = new ArrayList<>(); |
| | | List<Exception> exceptions = new ArrayList<>(); |
| | | ConfigFromDirContext cfg = new ConfigFromDirContext(); |
| | | cfg.updateTaskInformation(ctx, exceptions, taskEntries); |
| | | cfg.updateTaskInformation(conn.getLdapContext(), exceptions, taskEntries); |
| | | for (Exception ode : exceptions) |
| | | { |
| | | logger.warn(LocalizableMessage.raw("Error retrieving task entries: "+ode, ode)); |
| | |
| | | */ |
| | | sourceServerCI.initializeGlobalArguments(host1, port1, adminUid, bindDn1, pwd, |
| | | pwdFile == null ? null : new LinkedHashMap<String, String>(pwdFile)); |
| | | ConnectionWrapper ctx1 = null; |
| | | ConnectionWrapper conn1 = null; |
| | | |
| | | while (ctx1 == null && !cancelled) |
| | | while (conn1 == null && !cancelled) |
| | | { |
| | | try |
| | | { |
| | |
| | | bindDn1 = sourceServerCI.getBindDN(); |
| | | pwd1 = sourceServerCI.getBindPassword(); |
| | | |
| | | ctx1 = createConnectionInteracting(sourceServerCI); |
| | | if (ctx1 == null) |
| | | conn1 = createConnectionInteracting(sourceServerCI); |
| | | if (conn1 == null) |
| | | { |
| | | cancelled = true; |
| | | } |
| | |
| | | boolean secureReplication1 = argParser.server1.secureReplicationArg.isPresent(); |
| | | boolean configureReplicationServer1 = argParser.server1.configureReplicationServer(); |
| | | boolean configureReplicationDomain1 = argParser.server1.configureReplicationDomain(); |
| | | if (ctx1 != null) |
| | | if (conn1 != null) |
| | | { |
| | | int repPort1 = getReplicationPort(ctx1); |
| | | int repPort1 = getReplicationPort(conn1); |
| | | boolean replicationServer1Configured = repPort1 > 0; |
| | | if (replicationServer1Configured && !configureReplicationServer1) |
| | | { |
| | | final LocalizableMessage msg = |
| | | INFO_REPLICATION_SERVER_CONFIGURED_WARNING_PROMPT.get(ctx1.getHostPort(), repPort1); |
| | | INFO_REPLICATION_SERVER_CONFIGURED_WARNING_PROMPT.get(conn1.getHostPort(), repPort1); |
| | | if (!askConfirmation(msg, false)) |
| | | { |
| | | cancelled = true; |
| | |
| | | // eventually admin authentication data. |
| | | if (!cancelled) |
| | | { |
| | | AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(ctx1); |
| | | AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(conn1); |
| | | cancelled = !loadADSAndAcceptCertificates(sourceServerCI, aux, uData, true); |
| | | ctx1 = aux.get(); |
| | | conn1 = aux.get(); |
| | | } |
| | | if (!cancelled) |
| | | { |
| | | administratorDefined |= hasAdministrator(ctx1); |
| | | administratorDefined |= hasAdministrator(conn1); |
| | | if (uData.getAdminPwd() != null) |
| | | { |
| | | adminPwd = uData.getAdminPwd(); |
| | |
| | | pwdFile == null ? null : new LinkedHashMap<String, String>(pwdFile)); |
| | | destinationServerCI.setUseAdminOrBindDn(true); |
| | | } |
| | | ConnectionWrapper ctx2 = null; |
| | | |
| | | while (ctx2 == null && !cancelled) |
| | | ConnectionWrapper conn2 = null; |
| | | while (conn2 == null && !cancelled) |
| | | { |
| | | try |
| | | { |
| | |
| | | |
| | | if (!error) |
| | | { |
| | | ctx2 = createConnectionInteracting(destinationServerCI, true); |
| | | if (ctx2 == null) |
| | | conn2 = createConnectionInteracting(destinationServerCI, true); |
| | | if (conn2 == null) |
| | | { |
| | | cancelled = true; |
| | | } |
| | |
| | | boolean secureReplication2 = argParser.server2.secureReplicationArg.isPresent(); |
| | | boolean configureReplicationServer2 = argParser.server2.configureReplicationServer(); |
| | | boolean configureReplicationDomain2 = argParser.server2.configureReplicationDomain(); |
| | | if (ctx2 != null) |
| | | if (conn2 != null) |
| | | { |
| | | int repPort2 = getReplicationPort(ctx2); |
| | | int repPort2 = getReplicationPort(conn2); |
| | | boolean replicationServer2Configured = repPort2 > 0; |
| | | if (replicationServer2Configured && !configureReplicationServer2) |
| | | { |
| | | final LocalizableMessage prompt = |
| | | INFO_REPLICATION_SERVER_CONFIGURED_WARNING_PROMPT.get(ctx2.getHostPort(), repPort2); |
| | | INFO_REPLICATION_SERVER_CONFIGURED_WARNING_PROMPT.get(conn2.getHostPort(), repPort2); |
| | | if (!askConfirmation(prompt, false)) |
| | | { |
| | | cancelled = true; |
| | |
| | | // to load the ADS to ask the user to accept the certificates. |
| | | if (!cancelled) |
| | | { |
| | | AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(ctx2); |
| | | AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(conn2); |
| | | cancelled = !loadADSAndAcceptCertificates(destinationServerCI, aux, uData, false); |
| | | ctx2 = aux.get(); |
| | | conn2 = aux.get(); |
| | | } |
| | | if (!cancelled) |
| | | { |
| | | administratorDefined |= hasAdministrator(ctx2); |
| | | administratorDefined |= hasAdministrator(conn2); |
| | | } |
| | | } |
| | | uData.getServer2().setReplicationPort(replicationPort2); |
| | |
| | | if (!cancelled) |
| | | { |
| | | List<String> suffixes = argParser.getBaseDNs(); |
| | | checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, true, uData); |
| | | checkSuffixesForEnableReplication(suffixes, conn1, conn2, true, uData); |
| | | cancelled = suffixes.isEmpty(); |
| | | |
| | | uData.setBaseDNs(suffixes); |
| | | } |
| | | |
| | | close(ctx1, ctx2); |
| | | close(conn1, conn2); |
| | | uData.setReplicateSchema(!argParser.noSchemaReplication()); |
| | | |
| | | return !cancelled; |
| | |
| | | int port = argParser.getPortToDisable(); |
| | | |
| | | /* Try to connect to the server. */ |
| | | ConnectionWrapper ctx = null; |
| | | ConnectionWrapper conn = null; |
| | | |
| | | while (ctx == null && !cancelled) |
| | | while (conn == null && !cancelled) |
| | | { |
| | | try |
| | | { |
| | |
| | | adminUid = sourceServerCI.getProvidedAdminUID(); |
| | | adminPwd = sourceServerCI.getBindPassword(); |
| | | |
| | | ctx = createConnectionInteracting(sourceServerCI); |
| | | if (ctx == null) |
| | | conn = createConnectionInteracting(sourceServerCI); |
| | | if (conn == null) |
| | | { |
| | | cancelled = true; |
| | | } |
| | |
| | | uData.setBindDn(bindDn); |
| | | uData.setAdminPwd(adminPwd); |
| | | } |
| | | if (ctx != null && adminUid != null) |
| | | if (conn != null && adminUid != null) |
| | | { |
| | | // If the server contains an ADS, try to load it and only load it: if |
| | | // there are issues with the ADS they will be encountered in the |
| | | // disableReplication(DisableReplicationUserData) method. Here we have |
| | | // to load the ADS to ask the user to accept the certificates and |
| | | // eventually admin authentication data. |
| | | AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(ctx); |
| | | AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(conn); |
| | | cancelled = !loadADSAndAcceptCertificates(sourceServerCI, aux, uData, false); |
| | | ctx = aux.get(); |
| | | conn = aux.get(); |
| | | } |
| | | |
| | | boolean disableAll = argParser.disableAllArg.isPresent(); |
| | |
| | | cancelled = true; |
| | | } |
| | | } |
| | | int repPort = getReplicationPort(ctx); |
| | | int repPort = getReplicationPort(conn); |
| | | if (!disableAll |
| | | && (argParser.advancedArg.isPresent() || disableReplicationServer) |
| | | && repPort > 0) |
| | |
| | | if (disableReplicationServer && repPort < 0) |
| | | { |
| | | disableReplicationServer = false; |
| | | final LocalizableMessage msg = INFO_REPLICATION_PROMPT_NO_REPLICATION_SERVER_TO_DISABLE.get(ctx.getHostPort()); |
| | | final LocalizableMessage msg = INFO_REPLICATION_PROMPT_NO_REPLICATION_SERVER_TO_DISABLE.get(conn.getHostPort()); |
| | | try |
| | | { |
| | | cancelled = askConfirmation(msg, false, logger); |
| | |
| | | if (!cancelled && !disableAll) |
| | | { |
| | | List<String> suffixes = argParser.getBaseDNs(); |
| | | checkSuffixesForDisableReplication(suffixes, ctx.getLdapContext(), true, !disableReplicationServer); |
| | | checkSuffixesForDisableReplication(suffixes, conn, true, !disableReplicationServer); |
| | | cancelled = suffixes.isEmpty() && !disableReplicationServer; |
| | | |
| | | uData.setBaseDNs(suffixes); |
| | | |
| | | if (!uData.disableReplicationServer() && repPort > 0 && |
| | | disableAllBaseDns(ctx.getLdapContext(), uData) && !argParser.advancedArg.isPresent()) |
| | | if (!uData.disableReplicationServer() && repPort > 0 |
| | | && disableAllBaseDns(conn, uData) |
| | | && !argParser.advancedArg.isPresent()) |
| | | { |
| | | try |
| | | { |
| | | uData.setDisableReplicationServer(askConfirmation( |
| | | INFO_REPLICATION_DISABLE_ALL_SUFFIXES_DISABLE_REPLICATION_SERVER.get( |
| | | ctx.getHostPort(), repPort), true, |
| | | conn.getHostPort(), repPort), true, |
| | | logger)); |
| | | } |
| | | catch (ClientException ce) |
| | |
| | | } |
| | | } |
| | | |
| | | close(ctx); |
| | | close(conn); |
| | | |
| | | return !cancelled; |
| | | } |
| | |
| | | } |
| | | |
| | | List<String> suffixes = argParser.getBaseDNs(); |
| | | checkSuffixesForInitializeReplication(suffixes, conn.getLdapContext(), true); |
| | | checkSuffixesForInitializeReplication(suffixes, conn, true); |
| | | if (suffixes.isEmpty()) |
| | | { |
| | | return false; |
| | |
| | | */ |
| | | private boolean promptIfRequiredForPreOrPost(MonoServerReplicationUserData uData) |
| | | { |
| | | ConnectionWrapper ctx = null; |
| | | try |
| | | try (ConnectionWrapper conn = getConnection(uData)) |
| | | { |
| | | ctx = getConnection(uData); |
| | | if (ctx == null) |
| | | if (conn == null) |
| | | { |
| | | return false; |
| | | } |
| | | List<String> suffixes = argParser.getBaseDNs(); |
| | | checkSuffixesForInitializeReplication(suffixes, ctx.getLdapContext(), true); |
| | | checkSuffixesForInitializeReplication(suffixes, conn, true); |
| | | uData.setBaseDNs(suffixes); |
| | | return !suffixes.isEmpty(); |
| | | } |
| | | finally |
| | | { |
| | | close(ctx); |
| | | } |
| | | } |
| | | |
| | | private ConnectionWrapper getConnection(MonoServerReplicationUserData uData) |
| | |
| | | * @param uData the object to be updated. |
| | | * @return <CODE>true</CODE> if the object was successfully updated and |
| | | * <CODE>false</CODE> if the user cancelled the operation. |
| | | * @throws ReplicationCliException if a critical error occurs reading the |
| | | * ADS. |
| | | * @throws ReplicationCliException if a critical error occurs reading the ADS. |
| | | */ |
| | | private boolean promptIfRequired(StatusReplicationUserData uData) |
| | | throws ReplicationCliException |
| | | { |
| | | ConnectionWrapper ctx = null; |
| | | ConnectionWrapper conn = null; |
| | | try |
| | | { |
| | | ctx = getConnection(uData); |
| | | if (ctx == null) |
| | | conn = getConnection(uData); |
| | | if (conn == null) |
| | | { |
| | | return false; |
| | | } |
| | |
| | | // statusReplication(StatusReplicationUserData) method. Here we have |
| | | // to load the ADS to ask the user to accept the certificates and |
| | | // eventually admin authentication data. |
| | | AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(ctx); |
| | | AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(conn); |
| | | boolean cancelled = !loadADSAndAcceptCertificates(sourceServerCI, aux, uData, false); |
| | | ctx = aux.get(); |
| | | conn = aux.get(); |
| | | if (cancelled) |
| | | { |
| | | return false; |
| | |
| | | } |
| | | finally |
| | | { |
| | | close(ctx); |
| | | close(conn); |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | sourceServerCI.initializeGlobalArguments(hostSource, portSource, adminUid, null, adminPwd, |
| | | pwdFile == null ? null : new LinkedHashMap<String, String>(pwdFile)); |
| | | /* Try to connect to the source server. */ |
| | | ConnectionWrapper ctxSource = null; |
| | | |
| | | while (ctxSource == null && !cancelled) |
| | | // Try to connect to the source server |
| | | ConnectionWrapper connSource = null; |
| | | while (connSource == null && !cancelled) |
| | | { |
| | | try |
| | | { |
| | |
| | | adminUid = sourceServerCI.getAdministratorUID(); |
| | | adminPwd = sourceServerCI.getBindPassword(); |
| | | |
| | | ctxSource = createConnectionInteracting(sourceServerCI); |
| | | if (ctxSource == null) |
| | | connSource = createConnectionInteracting(sourceServerCI); |
| | | if (connSource == null) |
| | | { |
| | | cancelled = true; |
| | | } |
| | |
| | | argParser.getSecureArgsList()); |
| | | destinationServerCI.initializeGlobalArguments(hostDestination, portDestination, adminUid, null, adminPwd, |
| | | pwdFile == null ? null : new LinkedHashMap<String, String>(pwdFile)); |
| | | /* Try to connect to the destination server. */ |
| | | ConnectionWrapper ctxDestination = null; |
| | | |
| | | /* Try to connect to the destination server. */ |
| | | ConnectionWrapper connDestination = null; |
| | | destinationServerCI.resetHeadingDisplayed(); |
| | | while (ctxDestination == null && !cancelled) |
| | | while (connDestination == null && !cancelled) |
| | | { |
| | | try |
| | | { |
| | |
| | | |
| | | if (!error) |
| | | { |
| | | ctxDestination = createConnectionInteracting(destinationServerCI, true); |
| | | if (ctxDestination == null) |
| | | connDestination = createConnectionInteracting(destinationServerCI, true); |
| | | if (connDestination == null) |
| | | { |
| | | cancelled = true; |
| | | } |
| | |
| | | uData.setPortDestination(portDestination); |
| | | |
| | | List<String> suffixes = argParser.getBaseDNs(); |
| | | cancelled = serversOperations.continueAfterUserInput( |
| | | suffixes, ctxSource.getLdapContext(), ctxDestination.getLdapContext(), true); |
| | | cancelled = serversOperations.continueAfterUserInput(suffixes, connSource, connDestination, true); |
| | | uData.setBaseDNs(suffixes); |
| | | |
| | | if (!cancelled) |
| | | { |
| | | println(); |
| | | cancelled = serversOperations.confirmOperation( |
| | | uData, ctxSource.getLdapContext(), ctxDestination.getLdapContext(), true); |
| | | cancelled = serversOperations.confirmOperation(uData, connSource, connDestination, true); |
| | | println(); |
| | | } |
| | | } |
| | | |
| | | close(ctxSource, ctxDestination); |
| | | close(connSource, connDestination); |
| | | return !cancelled; |
| | | } |
| | | |
| | | private LocalizableMessage getInitializeReplicationPrompt(SourceDestinationServerUserData uData, |
| | | InitialLdapContext ctxSource, InitialLdapContext ctxDestination) |
| | | ConnectionWrapper connSource, ConnectionWrapper connDestination) |
| | | { |
| | | HostPort hostPortSource = getHostPort(ctxSource); |
| | | HostPort hostPortDestination = getHostPort(ctxDestination); |
| | | HostPort hostPortSource = connSource.getHostPort(); |
| | | HostPort hostPortDestination = connDestination.getHostPort(); |
| | | if (initializeADS(uData.getBaseDNs())) |
| | | { |
| | | final String adminSuffixDN = ADSContext.getAdministrationSuffixDN(); |
| | |
| | | getValueOrDefault(args.hostNameArg), getValueOrDefault(args.portArg))); |
| | | |
| | | String pwd = args.getBindPassword(); |
| | | if (pwd == null) |
| | | if (pwd == null || canConnectWithCredentials(server, adminDN, adminPwd)) |
| | | { |
| | | server.setBindDn(adminDN); |
| | | server.setPwd(adminPwd); |
| | | } |
| | | else |
| | | { |
| | | // Best-effort: try to use admin, if it does not work, use bind DN. |
| | | try |
| | | { |
| | | InitialLdapContext ctx = createAdministrativeContext(server.getHostPort(), |
| | | LDAPS.equals(connectiontype), START_TLS.equals(connectiontype), adminDN, adminPwd, |
| | | getConnectTimeout(), getTrustManager(sourceServerCI)); |
| | | server.setBindDn(adminDN); |
| | | server.setPwd(adminPwd); |
| | | ctx.close(); |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | server.setBindDn(getValueOrDefault(args.bindDnArg)); |
| | | server.setPwd(pwd); |
| | | } |
| | | server.setBindDn(getValueOrDefault(args.bindDnArg)); |
| | | server.setPwd(pwd); |
| | | } |
| | | } |
| | | |
| | | private boolean canConnectWithCredentials(EnableReplicationServerData server, String adminDN, String adminPwd) |
| | | { |
| | | try (ConnectionWrapper validCredentials = new ConnectionWrapper( |
| | | server.getHostPort(), connectionType, adminDN, adminPwd, getConnectTimeout(), getTrustManager(sourceServerCI))) |
| | | { |
| | | return true; |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Tells whether the server to which the LdapContext is connected has a |
| | | * replication port or not. |
| | | * @param connWrapper the InitialLdapContext to be used. |
| | | * @return <CODE>true</CODE> if the replication port for the server could |
| | | * be found and <CODE>false</CODE> otherwise. |
| | | * Tells whether the server for which a connection is provided has a replication port or not. |
| | | * |
| | | * @param conn |
| | | * the connection to be used. |
| | | * @return {@code true} if the server replication port could be found, {@code false} otherwise. |
| | | */ |
| | | private boolean hasReplicationPort(ConnectionWrapper connWrapper) |
| | | private boolean hasReplicationPort(ConnectionWrapper conn) |
| | | { |
| | | return getReplicationPort(connWrapper) != -1; |
| | | return getReplicationPort(conn) != -1; |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | private int getReplicationPort(ConnectionWrapper connWrapper) |
| | | { |
| | | int replicationPort = -1; |
| | | try |
| | | { |
| | | RootCfgClient root = connWrapper.getRootConfiguration(); |
| | |
| | | { |
| | | ReplicationServerCfgClient replicationServer = |
| | | sync.getReplicationServer(); |
| | | replicationPort = replicationServer.getReplicationPort(); |
| | | return replicationServer.getReplicationPort(); |
| | | } |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | logger.warn(LocalizableMessage.raw("Unexpected error retrieving the replication port: " + t, t)); |
| | | } |
| | | return replicationPort; |
| | | return -1; |
| | | } |
| | | |
| | | /** |
| | | * Loads the ADS with the provided context. If there are certificates to |
| | | * Loads the ADS with the provided connection. If there are certificates to |
| | | * be accepted we prompt them to the user. If there are errors loading the |
| | | * servers we display them to the user and we ask for confirmation. If the |
| | | * provided ctx is not using Global Administrator credentials, we prompt the |
| | | * provided connection is not using Global Administrator credentials, we prompt the |
| | | * user to provide them and update the provide ReplicationUserData |
| | | * accordingly. |
| | | * |
| | | * @param ci the LDAP connection to the server |
| | | * @param connWrapper the Ldap context to be used in an array: note the context |
| | | * @param connWrapper the connection to be used in an array: note the connection |
| | | * may be modified with the new credentials provided by the user. |
| | | * @param uData the ReplicationUserData to be updated. |
| | | * @param isFirstOrSourceServer whether this is the first server in the |
| | |
| | | { |
| | | boolean cancelled = false; |
| | | boolean triedWithUserProvidedAdmin = false; |
| | | final ConnectionWrapper connWrapper1 = connWrapper.get(); |
| | | final InitialLdapContext ctx1 = connWrapper1.getLdapContext(); |
| | | HostPort hostPort = connWrapper1.getHostPort(); |
| | | boolean isSSL = isSSL(ctx1); |
| | | boolean isStartTLS = isStartTLS(ctx1); |
| | | Type connectionType; |
| | | if (isSSL) |
| | | { |
| | | connectionType = LDAPS; |
| | | } |
| | | else if (isStartTLS) |
| | | { |
| | | connectionType = START_TLS; |
| | | } |
| | | else |
| | | { |
| | | connectionType = LDAP; |
| | | } |
| | | final ConnectionWrapper conn1 = connWrapper.get(); |
| | | HostPort hostPort = conn1.getHostPort(); |
| | | Type connectionType = getConnectionType(conn1); |
| | | if (getTrustManager(ci) == null) |
| | | { |
| | | // This is required when the user did connect to the server using SSL or |
| | |
| | | } |
| | | try |
| | | { |
| | | ADSContext adsContext = new ADSContext(connWrapper1); |
| | | ADSContext adsContext = new ADSContext(conn1); |
| | | if (adsContext.hasAdminData()) |
| | | { |
| | | boolean reloadTopology = true; |
| | |
| | | getTrustManager(ci), getConnectTimeout()); |
| | | cache.getFilter().setSearchMonitoringInformation(false); |
| | | cache.getFilter().setSearchBaseDNInformation(false); |
| | | cache.setPreferredConnections(getPreferredConnections(ctx1)); |
| | | cache.setPreferredConnections(getPreferredConnections(conn1)); |
| | | cache.reloadTopology(); |
| | | |
| | | reloadTopology = false; |
| | |
| | | if (!errorDisplayed) |
| | | { |
| | | println(); |
| | | println( |
| | | INFO_NOT_GLOBAL_ADMINISTRATOR_PROVIDED.get()); |
| | | println(INFO_NOT_GLOBAL_ADMINISTRATOR_PROVIDED.get()); |
| | | errorDisplayed = true; |
| | | } |
| | | adminUid = askForAdministratorUID( |
| | |
| | | adminPwd = askForAdministratorPwd(logger); |
| | | println(); |
| | | } |
| | | close(ctx1); |
| | | close(conn1); |
| | | try |
| | | { |
| | | final ConnectionWrapper connWrapper2 = new ConnectionWrapper( |
| | |
| | | cache = new TopologyCache(adsContext, getTrustManager(ci), getConnectTimeout()); |
| | | cache.getFilter().setSearchMonitoringInformation(false); |
| | | cache.getFilter().setSearchBaseDNInformation(false); |
| | | cache.setPreferredConnections(getPreferredConnections(connWrapper2.getLdapContext())); |
| | | cache.setPreferredConnections(getPreferredConnections(connWrapper2)); |
| | | connected = true; |
| | | } |
| | | catch (Throwable t) |
| | |
| | | return !cancelled; |
| | | } |
| | | |
| | | private Type getConnectionType(final ConnectionWrapper conn) |
| | | { |
| | | if (isSSL(conn.getLdapContext())) |
| | | { |
| | | return LDAPS; |
| | | } |
| | | else if (isStartTLS(conn.getLdapContext())) |
| | | { |
| | | return START_TLS; |
| | | } |
| | | else |
| | | { |
| | | return LDAP; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Tells whether there is a Global Administrator defined in the server |
| | | * to which the InitialLdapContext is connected. |
| | | * @param connWrapper the InitialLdapContext. |
| | | * @return <CODE>true</CODE> if we could find an administrator and |
| | | * <CODE>false</CODE> otherwise. |
| | | * Tells whether there is a Global Administrator defined in the server for which the connection is |
| | | * provided. |
| | | * |
| | | * @param conn |
| | | * the connection. |
| | | * @return {@code true} if we could find an administrator and {@code false} otherwise. |
| | | */ |
| | | private boolean hasAdministrator(ConnectionWrapper connWrapper) |
| | | private boolean hasAdministrator(ConnectionWrapper conn) |
| | | { |
| | | try |
| | | { |
| | | ADSContext adsContext = new ADSContext(connWrapper); |
| | | ADSContext adsContext = new ADSContext(conn); |
| | | if (adsContext.hasAdminData()) |
| | | { |
| | | Set<?> administrators = adsContext.readAdministratorRegistry(); |
| | |
| | | |
| | | /** |
| | | * Tells whether there is a Global Administrator corresponding to the provided |
| | | * ReplicationUserData defined in the server to which the InitialLdapContext |
| | | * is connected. |
| | | * @param connWrapper the InitialLdapContext. |
| | | * ReplicationUserData defined in the server for which the connection is provided. |
| | | * @param conn the connection |
| | | * @param uData the user data |
| | | * @return <CODE>true</CODE> if we could find an administrator and |
| | | * <CODE>false</CODE> otherwise. |
| | | */ |
| | | private boolean hasAdministrator(ConnectionWrapper connWrapper, |
| | | ReplicationUserData uData) |
| | | private boolean hasAdministrator(ConnectionWrapper conn, ReplicationUserData uData) |
| | | { |
| | | String adminUid = uData.getAdminUid(); |
| | | try |
| | | { |
| | | ADSContext adsContext = new ADSContext(connWrapper); |
| | | ADSContext adsContext = new ADSContext(conn); |
| | | Set<Map<AdministratorProperty, Object>> administrators = |
| | | adsContext.readAdministratorRegistry(); |
| | | for (Map<AdministratorProperty, Object> admin : administrators) |
| | |
| | | return false; |
| | | } |
| | | |
| | | /** Helper type for the {@link #getCommonSuffixes(InitialLdapContext, InitialLdapContext, SuffixRelationType)}. */ |
| | | /** Helper type for {@link #getCommonSuffixes(ConnectionWrapper, ConnectionWrapper, SuffixRelationType)}. */ |
| | | private enum SuffixRelationType |
| | | { |
| | | NOT_REPLICATED, FULLY_REPLICATED, REPLICATED, NOT_FULLY_REPLICATED, ALL |
| | |
| | | * replicated this list contains only the suffixes that are replicated |
| | | * between the servers or the list of suffixes that are not replicated |
| | | * between the servers). |
| | | * @param ctx1 the connection to the first server. |
| | | * @param ctx2 the connection to the second server. |
| | | * @param conn1 the connection to the first server. |
| | | * @param conn2 the connection to the second server. |
| | | * @param type whether to return a list with the suffixes that are |
| | | * replicated, fully replicated (replicas have exactly the same list of |
| | | * replication servers), not replicated or all the common suffixes. |
| | | * @return a Collection containing a list of suffixes that are replicated |
| | | * (or those that can be replicated) in two servers. |
| | | */ |
| | | private List<String> getCommonSuffixes(InitialLdapContext ctx1, InitialLdapContext ctx2, SuffixRelationType type) |
| | | private List<String> getCommonSuffixes(ConnectionWrapper conn1, ConnectionWrapper conn2, SuffixRelationType type) |
| | | { |
| | | LinkedList<String> suffixes = new LinkedList<>(); |
| | | try |
| | | { |
| | | TopologyCacheFilter filter = new TopologyCacheFilter(); |
| | | filter.setSearchMonitoringInformation(false); |
| | | ServerDescriptor server1 = ServerDescriptor.createStandalone(ctx1, filter); |
| | | ServerDescriptor server2 = ServerDescriptor.createStandalone(ctx2, filter); |
| | | ServerDescriptor server1 = ServerDescriptor.createStandalone(conn1.getLdapContext(), filter); |
| | | ServerDescriptor server2 = ServerDescriptor.createStandalone(conn2.getLdapContext(), filter); |
| | | |
| | | for (ReplicaDescriptor rep1 : server1.getReplicas()) |
| | | { |
| | |
| | | |
| | | /** |
| | | * Returns a Collection containing a list of replicas in a server. |
| | | * @param ctx the connection to the server. |
| | | * @param conn the connection to the server. |
| | | * @return a Collection containing a list of replicas in a server. |
| | | */ |
| | | private Collection<ReplicaDescriptor> getReplicas(InitialLdapContext ctx) |
| | | private Collection<ReplicaDescriptor> getReplicas(ConnectionWrapper conn) |
| | | { |
| | | LinkedList<ReplicaDescriptor> suffixes = new LinkedList<>(); |
| | | TopologyCacheFilter filter = new TopologyCacheFilter(); |
| | | filter.setSearchMonitoringInformation(false); |
| | | try |
| | | { |
| | | ServerDescriptor server = ServerDescriptor.createStandalone(ctx, filter); |
| | | ServerDescriptor server = ServerDescriptor.createStandalone(conn.getLdapContext(), filter); |
| | | suffixes.addAll(server.getReplicas()); |
| | | } |
| | | catch (Throwable t) |
| | |
| | | */ |
| | | private ReplicationCliReturnCode enableReplication(EnableReplicationUserData uData) |
| | | { |
| | | ConnectionWrapper ctx1 = null; |
| | | ConnectionWrapper ctx2 = null; |
| | | ConnectionWrapper conn1 = null; |
| | | ConnectionWrapper conn2 = null; |
| | | try |
| | | { |
| | | println(); |
| | | print(formatter.getFormattedWithPoints(INFO_REPLICATION_CONNECTING.get())); |
| | | |
| | | List<LocalizableMessage> errorMessages = new LinkedList<>(); |
| | | ctx1 = createAdministrativeConnection(uData.getServer1(), errorMessages); |
| | | ctx2 = createAdministrativeConnection(uData.getServer2(), errorMessages); |
| | | conn1 = createAdministrativeConnection(uData.getServer1(), errorMessages); |
| | | conn2 = createAdministrativeConnection(uData.getServer2(), errorMessages); |
| | | |
| | | if (!errorMessages.isEmpty()) |
| | | { |
| | |
| | | |
| | | if (!argParser.isInteractive()) |
| | | { |
| | | checksForNonInteractiveMode(uData, ctx1, ctx2, errorMessages); |
| | | checksForNonInteractiveMode(uData, conn1, conn2, errorMessages); |
| | | if (!errorMessages.isEmpty()) |
| | | { |
| | | errPrintLn(errorMessages); |
| | |
| | | } |
| | | |
| | | List<String> suffixes = uData.getBaseDNs(); |
| | | checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, false, uData); |
| | | checkSuffixesForEnableReplication(suffixes, conn1, conn2, false, uData); |
| | | if (suffixes.isEmpty()) |
| | | { |
| | | // The error messages are already displayed in the method |
| | |
| | | |
| | | if (!isInteractive()) |
| | | { |
| | | checkReplicationServerAlreadyConfigured(ctx1, uData.getServer1()); |
| | | checkReplicationServerAlreadyConfigured(ctx2, uData.getServer2()); |
| | | checkReplicationServerAlreadyConfigured(conn1, uData.getServer1()); |
| | | checkReplicationServerAlreadyConfigured(conn2, uData.getServer2()); |
| | | } |
| | | |
| | | try |
| | | { |
| | | updateConfiguration(ctx1, ctx2, uData); |
| | | printSuccessfullyEnabled(ctx1, ctx2); |
| | | updateConfiguration(conn1, conn2, uData); |
| | | printSuccessfullyEnabled(conn1, conn2); |
| | | return SUCCESSFUL; |
| | | } |
| | | catch (ReplicationCliException rce) |
| | |
| | | } |
| | | finally |
| | | { |
| | | close(ctx1, ctx2); |
| | | close(conn1, conn2); |
| | | } |
| | | } |
| | | |
| | |
| | | { |
| | | try |
| | | { |
| | | return new ConnectionWrapper(server.getHostPort(), connectiontype, server.getBindDn(), server.getPwd(), |
| | | return new ConnectionWrapper(server.getHostPort(), connectionType, server.getBindDn(), server.getPwd(), |
| | | getConnectTimeout(), getTrustManager(sourceServerCI)); |
| | | } |
| | | catch (NamingException e) |
| | |
| | | ? getAdministratorDN(uData.getAdminUid()) |
| | | : uData.getBindDn(); |
| | | |
| | | ConnectionWrapper connWrapper = createAdministrativeConnection(uData, bindDn); |
| | | if (connWrapper == null) |
| | | ConnectionWrapper conn = createAdministrativeConnection(uData, bindDn); |
| | | if (conn == null) |
| | | { |
| | | return ERROR_CONNECTING; |
| | | } |
| | |
| | | println(); |
| | | |
| | | List<String> suffixes = uData.getBaseDNs(); |
| | | checkSuffixesForDisableReplication( |
| | | suffixes, connWrapper.getLdapContext(), false, !uData.disableReplicationServer()); |
| | | checkSuffixesForDisableReplication(suffixes, conn, false, !uData.disableReplicationServer()); |
| | | if (suffixes.isEmpty() && !uData.disableReplicationServer() && !uData.disableAll()) |
| | | { |
| | | return REPLICATION_CANNOT_BE_DISABLED_ON_BASEDN; |
| | |
| | | |
| | | if (!isInteractive()) |
| | | { |
| | | boolean hasReplicationPort = hasReplicationPort(connWrapper); |
| | | boolean hasReplicationPort = hasReplicationPort(conn); |
| | | if (uData.disableAll() && hasReplicationPort) |
| | | { |
| | | uData.setDisableReplicationServer(true); |
| | |
| | | { |
| | | uData.setDisableReplicationServer(false); |
| | | println( |
| | | INFO_REPLICATION_WARNING_NO_REPLICATION_SERVER_TO_DISABLE.get(connWrapper.getHostPort())); |
| | | INFO_REPLICATION_WARNING_NO_REPLICATION_SERVER_TO_DISABLE.get(conn.getHostPort())); |
| | | println(); |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | if (!isInteractive() && !uData.disableReplicationServer() && !uData.disableAll() |
| | | && disableAllBaseDns(connWrapper.getLdapContext(), uData) && hasReplicationPort(connWrapper)) |
| | | && disableAllBaseDns(conn, uData) && hasReplicationPort(conn)) |
| | | { |
| | | // Inform the user that the replication server will not be disabled. |
| | | // Inform also of the user of the disableReplicationServerArg |
| | | println(INFO_REPLICATION_DISABLE_ALL_SUFFIXES_KEEP_REPLICATION_SERVER.get( |
| | | connWrapper.getHostPort(), |
| | | conn.getHostPort(), |
| | | argParser.disableReplicationServerArg.getLongIdentifier(), |
| | | argParser.disableAllArg.getLongIdentifier())); |
| | | } |
| | | try |
| | | { |
| | | updateConfiguration(connWrapper, uData); |
| | | updateConfiguration(conn, uData); |
| | | return SUCCESSFUL; |
| | | } |
| | | catch (ReplicationCliException rce) |
| | |
| | | } |
| | | finally |
| | | { |
| | | close(connWrapper); |
| | | close(conn); |
| | | } |
| | | } |
| | | |
| | |
| | | * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was |
| | | * successful and an error code otherwise. |
| | | */ |
| | | private ReplicationCliReturnCode statusReplication( |
| | | StatusReplicationUserData uData) |
| | | private ReplicationCliReturnCode statusReplication(StatusReplicationUserData uData) |
| | | { |
| | | final ConnectionWrapper ctx = createAdministrativeConnection(uData); |
| | | if (ctx == null) |
| | | final ConnectionWrapper conn = createAdministrativeConnection(uData); |
| | | if (conn == null) |
| | | { |
| | | return ERROR_CONNECTING; |
| | | } |
| | |
| | | { |
| | | try |
| | | { |
| | | displayStatus(ctx, uData); |
| | | displayStatus(conn, uData); |
| | | return SUCCESSFUL; |
| | | } |
| | | catch (ReplicationCliException rce) |
| | |
| | | } |
| | | finally |
| | | { |
| | | close(ctx); |
| | | close(conn); |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | private ReplicationCliReturnCode initializeReplication(SourceDestinationServerUserData uData) |
| | | { |
| | | InitialLdapContext ctxSource = createAdministrativeContext(uData, uData.getSource()); |
| | | InitialLdapContext ctxDestination = createAdministrativeContext(uData, uData.getDestination()); |
| | | ConnectionWrapper connSource = createAdministrativeConnection(uData, uData.getSource()); |
| | | ConnectionWrapper connDestination = createAdministrativeConnection(uData, uData.getDestination()); |
| | | try |
| | | { |
| | | if (ctxSource == null || ctxDestination == null) |
| | | if (connSource == null || connDestination == null) |
| | | { |
| | | return ERROR_CONNECTING; |
| | | } |
| | | |
| | | List<String> baseDNs = uData.getBaseDNs(); |
| | | checkSuffixesForInitializeReplication(baseDNs, ctxSource, ctxDestination, false); |
| | | checkSuffixesForInitializeReplication(baseDNs, connSource, connDestination, false); |
| | | if (baseDNs.isEmpty()) |
| | | { |
| | | return REPLICATION_CANNOT_BE_INITIALIZED_ON_BASEDN; |
| | |
| | | try |
| | | { |
| | | println(); |
| | | print(formatter.getFormattedProgress(INFO_PROGRESS_INITIALIZING_SUFFIX.get(baseDN, getHostPort(ctxSource)))); |
| | | print(formatter.getFormattedProgress( |
| | | INFO_PROGRESS_INITIALIZING_SUFFIX.get(baseDN, connSource.getHostPort()))); |
| | | println(); |
| | | initializeSuffix(baseDN, ctxSource, ctxDestination, true); |
| | | initializeSuffix(baseDN, connSource, connDestination, true); |
| | | returnValue = SUCCESSFUL; |
| | | } |
| | | catch (ReplicationCliException rce) |
| | |
| | | } |
| | | finally |
| | | { |
| | | close(ctxDestination, ctxSource); |
| | | close(connDestination, connSource); |
| | | } |
| | | } |
| | | |
| | | private InitialLdapContext createAdministrativeContext(SourceDestinationServerUserData uData, HostPort server) |
| | | private ConnectionWrapper createAdministrativeConnection(SourceDestinationServerUserData uData, HostPort server) |
| | | { |
| | | try |
| | | { |
| | | return createAdministrativeContext( |
| | | server, LDAPS.equals(connectiontype), START_TLS.equals(connectiontype), |
| | | getAdministratorDN(uData.getAdminUid()), uData.getAdminPwd(), |
| | | getConnectTimeout(), getTrustManager(sourceServerCI)); |
| | | return new ConnectionWrapper(server, connectionType, getAdministratorDN(uData.getAdminUid()), |
| | | uData.getAdminPwd(), getConnectTimeout(), getTrustManager(sourceServerCI)); |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | |
| | | private ReplicationCliReturnCode initializeAllReplication( |
| | | InitializeAllReplicationUserData uData) |
| | | { |
| | | final InitialLdapContext ctx = createAdministrativeContext(uData); |
| | | if (ctx == null) |
| | | final ConnectionWrapper conn = createAdministrativeConnection(uData); |
| | | if (conn == null) |
| | | { |
| | | return ERROR_CONNECTING; |
| | | } |
| | |
| | | try |
| | | { |
| | | List<String> baseDNs = uData.getBaseDNs(); |
| | | checkSuffixesForInitializeReplication(baseDNs, ctx, false); |
| | | checkSuffixesForInitializeReplication(baseDNs, conn, false); |
| | | if (baseDNs.isEmpty()) |
| | | { |
| | | return REPLICATION_CANNOT_BE_INITIALIZED_ON_BASEDN; |
| | |
| | | try |
| | | { |
| | | println(); |
| | | print(formatter.getFormattedProgress(INFO_PROGRESS_INITIALIZING_SUFFIX.get(baseDN, getHostPort(ctx)))); |
| | | print(formatter.getFormattedProgress(INFO_PROGRESS_INITIALIZING_SUFFIX.get(baseDN, conn.getHostPort()))); |
| | | println(); |
| | | initializeAllSuffix(baseDN, ctx, true); |
| | | initializeAllSuffix(baseDN, conn, true); |
| | | returnValue = SUCCESSFUL; |
| | | } |
| | | catch (ReplicationCliException rce) |
| | |
| | | } |
| | | finally |
| | | { |
| | | close(ctx); |
| | | close(conn); |
| | | } |
| | | } |
| | | |
| | |
| | | * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was |
| | | * successful and an error code otherwise. |
| | | */ |
| | | private ReplicationCliReturnCode preExternalInitialization( |
| | | PreExternalInitializationUserData uData) |
| | | private ReplicationCliReturnCode preExternalInitialization(PreExternalInitializationUserData uData) |
| | | { |
| | | InitialLdapContext ctx = createAdministrativeContext(uData); |
| | | if (ctx == null) |
| | | ConnectionWrapper conn = createAdministrativeConnection(uData); |
| | | if (conn == null) |
| | | { |
| | | return ERROR_CONNECTING; |
| | | } |
| | |
| | | try |
| | | { |
| | | List<String> baseDNs = uData.getBaseDNs(); |
| | | checkSuffixesForInitializeReplication(baseDNs, ctx, false); |
| | | checkSuffixesForInitializeReplication(baseDNs, conn, false); |
| | | if (baseDNs.isEmpty()) |
| | | { |
| | | return REPLICATION_CANNOT_BE_INITIALIZED_ON_BASEDN; |
| | |
| | | { |
| | | println(); |
| | | print(formatter.getFormattedWithPoints(INFO_PROGRESS_PRE_EXTERNAL_INITIALIZATION.get(baseDN))); |
| | | preExternalInitialization(baseDN, ctx); |
| | | preExternalInitialization(baseDN, conn); |
| | | print(formatter.getFormattedDone()); |
| | | println(); |
| | | } |
| | |
| | | } |
| | | finally |
| | | { |
| | | close(ctx); |
| | | close(conn); |
| | | } |
| | | } |
| | | |
| | |
| | | * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was |
| | | * successful and an error code otherwise. |
| | | */ |
| | | private ReplicationCliReturnCode postExternalInitialization( |
| | | PostExternalInitializationUserData uData) |
| | | private ReplicationCliReturnCode postExternalInitialization(PostExternalInitializationUserData uData) |
| | | { |
| | | InitialLdapContext ctx = createAdministrativeContext(uData); |
| | | if (ctx == null) |
| | | ConnectionWrapper conn = createAdministrativeConnection(uData); |
| | | if (conn == null) |
| | | { |
| | | return ERROR_CONNECTING; |
| | | } |
| | |
| | | try |
| | | { |
| | | List<String> baseDNs = uData.getBaseDNs(); |
| | | checkSuffixesForInitializeReplication(baseDNs, ctx, false); |
| | | checkSuffixesForInitializeReplication(baseDNs, conn, false); |
| | | if (baseDNs.isEmpty()) |
| | | { |
| | | return REPLICATION_CANNOT_BE_INITIALIZED_ON_BASEDN; |
| | |
| | | { |
| | | println(); |
| | | print(formatter.getFormattedWithPoints(INFO_PROGRESS_POST_EXTERNAL_INITIALIZATION.get(baseDN))); |
| | | postExternalInitialization(baseDN, ctx); |
| | | postExternalInitialization(baseDN, conn); |
| | | println(formatter.getFormattedDone()); |
| | | println(); |
| | | } |
| | |
| | | } |
| | | finally |
| | | { |
| | | close(ctx); |
| | | close(conn); |
| | | } |
| | | } |
| | | |
| | |
| | | * @param suffixes the suffixes provided by the user. This Collection is |
| | | * updated by removing the base DNs that cannot be enabled and with the |
| | | * base DNs that the user provided interactively. |
| | | * @param ctx1 connection to the first server. |
| | | * @param ctx2 connection to the second server. |
| | | * @param conn1 connection to the first server. |
| | | * @param conn2 connection to the second server. |
| | | * @param interactive whether to ask the user to provide interactively |
| | | * base DNs if none of the provided base DNs can be enabled. |
| | | * @param uData the user data. This object will not be updated by this method |
| | |
| | | * replication domains must be configured or not. |
| | | */ |
| | | private void checkSuffixesForEnableReplication(Collection<String> suffixes, |
| | | ConnectionWrapper ctx1, ConnectionWrapper ctx2, |
| | | ConnectionWrapper conn1, ConnectionWrapper conn2, |
| | | boolean interactive, EnableReplicationUserData uData) |
| | | { |
| | | EnableReplicationServerData server1 = uData.getServer1(); |
| | |
| | | if (server1.configureReplicationDomain() && |
| | | server2.configureReplicationDomain()) |
| | | { |
| | | availableSuffixes.addAll(getCommonSuffixes(ctx1.getLdapContext(), ctx2.getLdapContext(), |
| | | SuffixRelationType.NOT_FULLY_REPLICATED)); |
| | | alreadyReplicatedSuffixes.addAll(getCommonSuffixes(ctx1.getLdapContext(), ctx2.getLdapContext(), |
| | | SuffixRelationType.FULLY_REPLICATED)); |
| | | availableSuffixes.addAll(getCommonSuffixes(conn1, conn2, SuffixRelationType.NOT_FULLY_REPLICATED)); |
| | | alreadyReplicatedSuffixes.addAll(getCommonSuffixes(conn1, conn2, SuffixRelationType.FULLY_REPLICATED)); |
| | | } |
| | | else if (server1.configureReplicationDomain()) |
| | | { |
| | | updateAvailableAndReplicatedSuffixesForOneDomain(ctx1, ctx2, |
| | | updateAvailableAndReplicatedSuffixesForOneDomain(conn1, conn2, |
| | | availableSuffixes, alreadyReplicatedSuffixes); |
| | | } |
| | | else if (server2.configureReplicationDomain()) |
| | | { |
| | | updateAvailableAndReplicatedSuffixesForOneDomain(ctx2, ctx1, |
| | | updateAvailableAndReplicatedSuffixesForOneDomain(conn2, conn1, |
| | | availableSuffixes, alreadyReplicatedSuffixes); |
| | | } |
| | | else |
| | | { |
| | | updateAvailableAndReplicatedSuffixesForNoDomain(ctx1, ctx2, |
| | | updateAvailableAndReplicatedSuffixesForNoDomain(conn1, conn2, |
| | | availableSuffixes, alreadyReplicatedSuffixes); |
| | | } |
| | | |
| | |
| | | * @param suffixes the suffixes provided by the user. This Collection is |
| | | * updated by removing the base DNs that cannot be disabled and with the |
| | | * base DNs that the user provided interactively. |
| | | * @param ctx connection to the server. |
| | | * @param conn connection to the server. |
| | | * @param interactive whether to ask the user to provide interactively |
| | | * base DNs if none of the provided base DNs can be disabled. |
| | | * @param displayErrors whether to display errors or not. |
| | | */ |
| | | private void checkSuffixesForDisableReplication(Collection<String> suffixes, |
| | | InitialLdapContext ctx, boolean interactive, boolean displayErrors) |
| | | ConnectionWrapper conn, boolean interactive, boolean displayErrors) |
| | | { |
| | | // whether the user must provide base DNs or not |
| | | // (if it is <CODE>false</CODE> the user will be proposed the suffixes only once) |
| | |
| | | TreeSet<String> availableSuffixes = new TreeSet<>(); |
| | | TreeSet<String> notReplicatedSuffixes = new TreeSet<>(); |
| | | |
| | | Collection<ReplicaDescriptor> replicas = getReplicas(ctx); |
| | | Collection<ReplicaDescriptor> replicas = getReplicas(conn); |
| | | for (ReplicaDescriptor rep : replicas) |
| | | { |
| | | String dn = rep.getSuffix().getDN(); |
| | |
| | | * @param suffixes the suffixes provided by the user. This Collection is |
| | | * updated by removing the base DNs that cannot be initialized and with the |
| | | * base DNs that the user provided interactively. |
| | | * @param ctx connection to the server. |
| | | * @param conn connection to the server. |
| | | * @param interactive whether to ask the user to provide interactively |
| | | * base DNs if none of the provided base DNs can be initialized. |
| | | */ |
| | | private void checkSuffixesForInitializeReplication( |
| | | Collection<String> suffixes, InitialLdapContext ctx, boolean interactive) |
| | | Collection<String> suffixes, ConnectionWrapper conn, boolean interactive) |
| | | { |
| | | TreeSet<String> availableSuffixes = new TreeSet<>(); |
| | | TreeSet<String> notReplicatedSuffixes = new TreeSet<>(); |
| | | |
| | | Collection<ReplicaDescriptor> replicas = getReplicas(ctx); |
| | | Collection<ReplicaDescriptor> replicas = getReplicas(conn); |
| | | for (ReplicaDescriptor rep : replicas) |
| | | { |
| | | String dn = rep.getSuffix().getDN(); |
| | |
| | | * @param suffixes the suffixes provided by the user. This Collection is |
| | | * updated by removing the base DNs that cannot be enabled and with the |
| | | * base DNs that the user provided interactively. |
| | | * @param ctxSource connection to the source server. |
| | | * @param ctxDestination connection to the destination server. |
| | | * @param connSource connection to the source server. |
| | | * @param connDestination connection to the destination server. |
| | | * @param interactive whether to ask the user to provide interactively |
| | | * base DNs if none of the provided base DNs can be initialized. |
| | | */ |
| | | private void checkSuffixesForInitializeReplication( |
| | | Collection<String> suffixes, InitialLdapContext ctxSource, |
| | | InitialLdapContext ctxDestination, boolean interactive) |
| | | private void checkSuffixesForInitializeReplication(Collection<String> suffixes, ConnectionWrapper connSource, |
| | | ConnectionWrapper connDestination, boolean interactive) |
| | | { |
| | | TreeSet<String> availableSuffixes = new TreeSet<>( |
| | | getCommonSuffixes(ctxSource, ctxDestination, SuffixRelationType.REPLICATED)); |
| | | getCommonSuffixes(connSource, connDestination, SuffixRelationType.REPLICATED)); |
| | | if (availableSuffixes.isEmpty()) |
| | | { |
| | | errPrintln(); |
| | |
| | | /** |
| | | * Updates the configuration in the two servers (and in other servers if |
| | | * they are referenced) to enable replication. |
| | | * @param ctx1 the connection to the first server. |
| | | * @param ctx2 the connection to the second server. |
| | | * @param conn1 the connection to the first server. |
| | | * @param conn2 the connection to the second server. |
| | | * @param uData the EnableReplicationUserData object containing the required |
| | | * parameters to update the configuration. |
| | | * @throws ReplicationCliException if there is an error. |
| | | */ |
| | | private void updateConfiguration(ConnectionWrapper ctx1, ConnectionWrapper ctx2, EnableReplicationUserData uData) |
| | | private void updateConfiguration(ConnectionWrapper conn1, ConnectionWrapper conn2, EnableReplicationUserData uData) |
| | | throws ReplicationCliException |
| | | { |
| | | final Set<String> twoReplServers = new LinkedHashSet<>(); |
| | |
| | | filter.addBaseDNToSearch(ADSContext.getAdministrationSuffixDN()); |
| | | filter.addBaseDNToSearch(Constants.SCHEMA_DN); |
| | | addBaseDNs(filter, uData.getBaseDNs()); |
| | | ServerDescriptor serverDesc1 = createStandalone(ctx1, filter); |
| | | ServerDescriptor serverDesc2 = createStandalone(ctx2, filter); |
| | | ServerDescriptor serverDesc1 = createStandalone(conn1, filter); |
| | | ServerDescriptor serverDesc2 = createStandalone(conn2, filter); |
| | | |
| | | ADSContext adsCtx1 = new ADSContext(ctx1); |
| | | ADSContext adsCtx2 = new ADSContext(ctx2); |
| | | ADSContext adsCtx1 = new ADSContext(conn1); |
| | | ADSContext adsCtx2 = new ADSContext(conn2); |
| | | |
| | | if (!argParser.isInteractive()) |
| | | { |
| | |
| | | try |
| | | { |
| | | final Set<PreferredConnection> cnx = new LinkedHashSet<>(); |
| | | cnx.addAll(getPreferredConnections(ctx1.getLdapContext())); |
| | | cnx.addAll(getPreferredConnections(ctx2.getLdapContext())); |
| | | cnx.addAll(getPreferredConnections(conn1)); |
| | | cnx.addAll(getPreferredConnections(conn2)); |
| | | TopologyCache cache1 = createTopologyCache(adsCtx1, cnx, uData); |
| | | if (cache1 != null) |
| | | { |
| | |
| | | |
| | | // These are used to identify which server we use to initialize |
| | | // the contents of the other server (if any). |
| | | ConnectionWrapper ctxSource = null; |
| | | ConnectionWrapper ctxDestination = null; |
| | | ConnectionWrapper connSource = null; |
| | | ConnectionWrapper connDestination = null; |
| | | ADSContext adsCtxSource = null; |
| | | |
| | | boolean adsAlreadyReplicated = false; |
| | |
| | | registerServer(adsCtx1, serverDesc1.getAdsProperties()); |
| | | } |
| | | |
| | | ctxSource = ctx1; |
| | | ctxDestination = ctx2; |
| | | connSource = conn1; |
| | | connDestination = conn2; |
| | | adsCtxSource = adsCtx1; |
| | | } |
| | | else if (registry1.size() <= 1) |
| | |
| | | registerServer(adsCtx2, serverDesc2.getAdsProperties()); |
| | | } |
| | | |
| | | ctxSource = ctx2; |
| | | ctxDestination = ctx1; |
| | | connSource = conn2; |
| | | connDestination = conn1; |
| | | adsCtxSource = adsCtx2; |
| | | } |
| | | else if (!areEqual(registry1, registry2)) |
| | |
| | | println(); |
| | | |
| | | boolean isFirstSource = mergeRegistries(adsCtx1, adsCtx2); |
| | | ctxSource = isFirstSource ? ctx1 : ctx2; |
| | | connSource = isFirstSource ? conn1 : conn2; |
| | | adsMergeDone = true; |
| | | } |
| | | else |
| | |
| | | println(); |
| | | |
| | | boolean isFirstSource = mergeRegistries(adsCtx1, adsCtx2); |
| | | ctxSource = isFirstSource ? ctx1 : ctx2; |
| | | connSource = isFirstSource ? conn1 : conn2; |
| | | adsMergeDone = true; |
| | | } |
| | | else if (isADS1Replicated || !isADS2Replicated) |
| | |
| | | registerServer(adsCtx1, serverDesc1.getAdsProperties()); |
| | | } |
| | | |
| | | ctxSource = ctx1; |
| | | ctxDestination = ctx2; |
| | | connSource = conn1; |
| | | connDestination = conn2; |
| | | adsCtxSource = adsCtx1; |
| | | } |
| | | else if (isADS2Replicated) |
| | |
| | | registerServer(adsCtx2, serverDesc2.getAdsProperties()); |
| | | } |
| | | |
| | | ctxSource = ctx2; |
| | | ctxDestination = ctx1; |
| | | connSource = conn2; |
| | | connDestination = conn1; |
| | | adsCtxSource = adsCtx2; |
| | | } |
| | | } |
| | |
| | | registerServer(adsCtx2, serverDesc2.getAdsProperties()); |
| | | } |
| | | |
| | | ctxSource = ctx2; |
| | | ctxDestination = ctx1; |
| | | connSource = conn2; |
| | | connDestination = conn1; |
| | | adsCtxSource = adsCtx2; |
| | | } |
| | | else if (adsCtx1.hasAdminData() && !adsCtx2.hasAdminData()) |
| | |
| | | registerServer(adsCtx1, serverDesc1.getAdsProperties()); |
| | | } |
| | | |
| | | ctxSource = ctx1; |
| | | ctxDestination = ctx2; |
| | | connSource = conn1; |
| | | connDestination = conn2; |
| | | adsCtxSource = adsCtx1; |
| | | } |
| | | else |
| | | { |
| | | adsCtx1.createAdminData(null); |
| | | if (!hasAdministrator(ctx1, uData)) |
| | | if (!hasAdministrator(conn1, uData)) |
| | | { |
| | | // This could occur if the user created an administrator without |
| | | // registering any server. |
| | |
| | | serverDesc2.updateAdsPropertiesWithServerProperties(); |
| | | adsCtx1.registerServer(serverDesc2.getAdsProperties()); |
| | | |
| | | ctxSource = ctx1; |
| | | ctxDestination = ctx2; |
| | | connSource = conn1; |
| | | connDestination = conn2; |
| | | adsCtxSource = adsCtx1; |
| | | } |
| | | } |
| | |
| | | { |
| | | try |
| | | { |
| | | ServerDescriptor.seedAdsTrustStore(ctxDestination.getLdapContext(), adsCtxSource.getTrustedCertificates()); |
| | | ServerDescriptor.seedAdsTrustStore(connDestination.getLdapContext(), adsCtxSource.getTrustedCertificates()); |
| | | } |
| | | catch (Throwable t) |
| | | { |
| | | logger.error(LocalizableMessage.raw("Error seeding truststores: "+t, t)); |
| | | throw new ReplicationCliException( |
| | | ERR_REPLICATION_ENABLE_SEEDING_TRUSTSTORE.get(ctxDestination.getHostPort(), |
| | | ERR_REPLICATION_ENABLE_SEEDING_TRUSTSTORE.get(connDestination.getHostPort(), |
| | | adsCtxSource.getHostPort(), toString(t)), |
| | | ERROR_SEEDING_TRUSTORE, t); |
| | | } |
| | |
| | | try |
| | | { |
| | | Set<PreferredConnection> cnx = new LinkedHashSet<>(); |
| | | cnx.addAll(getPreferredConnections(ctx1.getLdapContext())); |
| | | cnx.addAll(getPreferredConnections(ctx2.getLdapContext())); |
| | | cnx.addAll(getPreferredConnections(conn1)); |
| | | cnx.addAll(getPreferredConnections(conn2)); |
| | | cache1 = createTopologyCache(adsCtx1, cnx, uData); |
| | | if (cache1 != null) |
| | | { |
| | |
| | | ERROR_READING_TOPOLOGY_CACHE, tce); |
| | | } |
| | | |
| | | addToSets(serverDesc1, uData.getServer1(), ctx1, twoReplServers, usedReplicationServerIds); |
| | | addToSets(serverDesc2, uData.getServer2(), ctx2, twoReplServers, usedReplicationServerIds); |
| | | addToSets(serverDesc1, uData.getServer1(), conn1, twoReplServers, usedReplicationServerIds); |
| | | addToSets(serverDesc2, uData.getServer2(), conn2, twoReplServers, usedReplicationServerIds); |
| | | |
| | | for (String baseDN : uData.getBaseDNs()) |
| | | { |
| | |
| | | } |
| | | |
| | | Set<String> alreadyConfiguredReplicationServers = new HashSet<>(); |
| | | configureServer(ctx1, serverDesc1, uData.getServer1(), argParser.server1.replicationPortArg, |
| | | configureServer(conn1, serverDesc1, uData.getServer1(), argParser.server1.replicationPortArg, |
| | | usedReplicationServerIds, allRepServers, alreadyConfiguredReplicationServers, |
| | | WARN_FIRST_REPLICATION_SERVER_ALREADY_CONFIGURED); |
| | | configureServer(ctx2, serverDesc2, uData.getServer2(), argParser.server2.replicationPortArg, |
| | | configureServer(conn2, serverDesc2, uData.getServer2(), argParser.server2.replicationPortArg, |
| | | usedReplicationServerIds, allRepServers, alreadyConfiguredReplicationServers, |
| | | WARN_SECOND_REPLICATION_SERVER_ALREADY_CONFIGURED); |
| | | |
| | |
| | | Set<Integer> usedIds = hmUsedReplicationDomainIds.get(baseDN); |
| | | Set<String> alreadyConfiguredServers = new HashSet<>(); |
| | | |
| | | configureToReplicateBaseDN(uData.getServer1(), ctx1, serverDesc1, cache1, baseDN, |
| | | configureToReplicateBaseDN(uData.getServer1(), conn1, serverDesc1, cache1, baseDN, |
| | | usedIds, alreadyConfiguredServers, repServers, allRepServers, alreadyConfiguredReplicationServers); |
| | | |
| | | configureToReplicateBaseDN(uData.getServer2(), ctx2, serverDesc2, cache2, baseDN, |
| | | configureToReplicateBaseDN(uData.getServer2(), conn2, serverDesc2, cache2, baseDN, |
| | | usedIds, alreadyConfiguredServers, repServers, allRepServers, alreadyConfiguredReplicationServers); |
| | | } |
| | | |
| | |
| | | if (adsMergeDone) |
| | | { |
| | | PointAdder pointAdder = new PointAdder(this); |
| | | print(INFO_ENABLE_REPLICATION_INITIALIZING_ADS_ALL.get(ctxSource.getHostPort())); |
| | | print(INFO_ENABLE_REPLICATION_INITIALIZING_ADS_ALL.get(connSource.getHostPort())); |
| | | pointAdder.start(); |
| | | try |
| | | { |
| | | initializeAllSuffix(ADSContext.getAdministrationSuffixDN(), ctxSource.getLdapContext(), false); |
| | | initializeAllSuffix(ADSContext.getAdministrationSuffixDN(), connSource, false); |
| | | } |
| | | finally |
| | | { |
| | |
| | | print(formatter.getFormattedDone()); |
| | | println(); |
| | | } |
| | | else if (ctxSource != null && ctxDestination != null) |
| | | else if (connSource != null && connDestination != null) |
| | | { |
| | | print(formatter.getFormattedWithPoints( |
| | | INFO_ENABLE_REPLICATION_INITIALIZING_ADS.get(ctxDestination.getHostPort(), ctxSource.getHostPort()))); |
| | | INFO_ENABLE_REPLICATION_INITIALIZING_ADS.get( |
| | | connDestination.getHostPort(), connSource.getHostPort()))); |
| | | |
| | | initializeSuffix( |
| | | ADSContext.getAdministrationSuffixDN(), ctxSource.getLdapContext(), ctxDestination.getLdapContext(), false); |
| | | initializeSuffix(ADSContext.getAdministrationSuffixDN(), connSource, connDestination, false); |
| | | print(formatter.getFormattedDone()); |
| | | println(); |
| | | } |
| | |
| | | { |
| | | if (argParser.useSecondServerAsSchemaSource()) |
| | | { |
| | | ctxSource = ctx2; |
| | | ctxDestination = ctx1; |
| | | connSource = conn2; |
| | | connDestination = conn1; |
| | | } |
| | | else |
| | | { |
| | | ctxSource = ctx1; |
| | | ctxDestination = ctx2; |
| | | connSource = conn1; |
| | | connDestination = conn2; |
| | | } |
| | | if (adsMergeDone) |
| | | { |
| | | PointAdder pointAdder = new PointAdder(this); |
| | | println(INFO_ENABLE_REPLICATION_INITIALIZING_SCHEMA.get( |
| | | ctxDestination.getHostPort(), ctxSource.getHostPort())); |
| | | connDestination.getHostPort(), connSource.getHostPort())); |
| | | pointAdder.start(); |
| | | try |
| | | { |
| | | initializeAllSuffix(Constants.SCHEMA_DN, ctxSource.getLdapContext(), false); |
| | | initializeAllSuffix(Constants.SCHEMA_DN, connSource, false); |
| | | } |
| | | finally |
| | | { |
| | |
| | | else |
| | | { |
| | | print(formatter.getFormattedWithPoints(INFO_ENABLE_REPLICATION_INITIALIZING_SCHEMA.get( |
| | | ctxDestination.getHostPort(), ctxSource.getHostPort()))); |
| | | initializeSuffix(Constants.SCHEMA_DN, ctxSource.getLdapContext(), ctxDestination.getLdapContext(), false); |
| | | connDestination |
| | | .getHostPort(), connSource.getHostPort()))); |
| | | initializeSuffix(Constants.SCHEMA_DN, connSource, connDestination, false); |
| | | } |
| | | print(formatter.getFormattedDone()); |
| | | println(); |
| | |
| | | } |
| | | } |
| | | |
| | | private void configureToReplicateBaseDN(EnableReplicationServerData server, ConnectionWrapper ctx, |
| | | private void configureToReplicateBaseDN(EnableReplicationServerData server, ConnectionWrapper conn, |
| | | ServerDescriptor serverDesc, TopologyCache cache, String baseDN, Set<Integer> usedIds, |
| | | Set<String> alreadyConfiguredServers, Set<String> repServers, final Set<String> allRepServers, |
| | | Set<String> alreadyConfiguredReplicationServers) throws ReplicationCliException |
| | |
| | | { |
| | | try |
| | | { |
| | | configureToReplicateBaseDN(ctx, baseDN, repServers, usedIds); |
| | | configureToReplicateBaseDN(conn, baseDN, repServers, usedIds); |
| | | } |
| | | catch (Exception ode) |
| | | catch (Exception e) |
| | | { |
| | | LocalizableMessage msg = getMessageForEnableException(ctx.getHostPort(), baseDN); |
| | | throw new ReplicationCliException(msg, ERROR_ENABLING_REPLICATION_ON_BASEDN, ode); |
| | | LocalizableMessage msg = getMessageForEnableException(conn.getHostPort(), baseDN); |
| | | throw new ReplicationCliException(msg, ERROR_ENABLING_REPLICATION_ON_BASEDN, e); |
| | | } |
| | | } |
| | | alreadyConfiguredServers.add(serverDesc.getId()); |
| | |
| | | } |
| | | } |
| | | |
| | | private void configureServer(ConnectionWrapper ctx, ServerDescriptor serverDesc, |
| | | private void configureServer(ConnectionWrapper conn, ServerDescriptor serverDesc, |
| | | EnableReplicationServerData enableServer, IntegerArgument replicationPortArg, |
| | | Set<Integer> usedReplicationServerIds, Set<String> allRepServers, |
| | | Set<String> alreadyConfiguredReplicationServers, Arg2<Number, Number> replicationServerAlreadyConfiguredMsg) |
| | |
| | | { |
| | | try |
| | | { |
| | | configureAsReplicationServer(ctx, enableServer.getReplicationPort(), enableServer.isSecureReplication(), |
| | | configureAsReplicationServer(conn, enableServer.getReplicationPort(), enableServer.isSecureReplication(), |
| | | allRepServers, usedReplicationServerIds); |
| | | } |
| | | catch (Exception ode) |
| | | { |
| | | throw errorConfiguringReplicationServer(ctx, ode); |
| | | throw errorConfiguringReplicationServer(conn, ode); |
| | | } |
| | | } |
| | | else if (serverDesc.isReplicationServer()) |
| | | { |
| | | try |
| | | { |
| | | updateReplicationServer(ctx, allRepServers); |
| | | updateReplicationServer(conn, allRepServers); |
| | | } |
| | | catch (Exception ode) |
| | | { |
| | | throw errorConfiguringReplicationServer(ctx, ode); |
| | | throw errorConfiguringReplicationServer(conn, ode); |
| | | } |
| | | if (replicationPortArg.isPresent() && enableServer.getReplicationPort() != serverDesc.getReplicationServerPort()) |
| | | { |
| | |
| | | } |
| | | |
| | | /** |
| | | * Updates the configuration in the server (and in other servers if |
| | | * they are referenced) to disable replication. |
| | | * @param ctx the connection to the server. |
| | | * @param uData the DisableReplicationUserData object containing the required |
| | | * parameters to update the configuration. |
| | | * @throws ReplicationCliException if there is an error. |
| | | * Updates the configuration in the server (and in other servers if they are referenced) to |
| | | * disable replication. |
| | | * |
| | | * @param conn |
| | | * the connection to the server. |
| | | * @param uData |
| | | * the DisableReplicationUserData object containing the required parameters to update the |
| | | * configuration. |
| | | * @throws ReplicationCliException |
| | | * if there is an error. |
| | | */ |
| | | private void updateConfiguration(ConnectionWrapper ctx, |
| | | DisableReplicationUserData uData) throws ReplicationCliException |
| | | private void updateConfiguration(ConnectionWrapper conn, DisableReplicationUserData uData) |
| | | throws ReplicationCliException |
| | | { |
| | | TopologyCacheFilter filter = new TopologyCacheFilter(); |
| | | filter.setSearchMonitoringInformation(false); |
| | |
| | | filter.addBaseDNToSearch(ADSContext.getAdministrationSuffixDN()); |
| | | addBaseDNs(filter, uData.getBaseDNs()); |
| | | } |
| | | ServerDescriptor server = createStandalone(ctx, filter); |
| | | ServerDescriptor server = createStandalone(conn, filter); |
| | | |
| | | ADSContext adsCtx = new ADSContext(ctx); |
| | | ADSContext adsCtx = new ADSContext(conn); |
| | | |
| | | TopologyCache cache = null; |
| | | // Only try to update remote server if the user provided a Global |
| | |
| | | if (adsCtx.hasAdminData() && tryToUpdateRemote) |
| | | { |
| | | cache = new TopologyCache(adsCtx, getTrustManager(sourceServerCI), getConnectTimeout()); |
| | | cache.setPreferredConnections(getPreferredConnections(ctx.getLdapContext())); |
| | | cache.setPreferredConnections(getPreferredConnections(conn)); |
| | | cache.getFilter().setSearchMonitoringInformation(false); |
| | | if (!uData.disableAll()) |
| | | { |
| | |
| | | boolean forceDisableADS = false; |
| | | boolean schemaReplicated = false; |
| | | boolean adsReplicated = false; |
| | | boolean disableAllBaseDns = disableAllBaseDns(ctx.getLdapContext(), uData); |
| | | boolean disableAllBaseDns = disableAllBaseDns(conn, uData); |
| | | |
| | | Collection<ReplicaDescriptor> replicas = getReplicas(ctx.getLdapContext()); |
| | | Collection<ReplicaDescriptor> replicas = getReplicas(conn); |
| | | for (ReplicaDescriptor rep : replicas) |
| | | { |
| | | String dn = rep.getSuffix().getDN(); |
| | |
| | | { |
| | | try |
| | | { |
| | | deleteReplicationDomain(ctx, baseDN); |
| | | deleteReplicationDomain(conn, baseDN); |
| | | } |
| | | catch (OpenDsException ode) |
| | | { |
| | | LocalizableMessage msg = getMessageForDisableException(ctx.getHostPort(), baseDN); |
| | | LocalizableMessage msg = getMessageForDisableException(conn.getHostPort(), baseDN); |
| | | throw new ReplicationCliException(msg, ERROR_DISABLING_REPLICATION_ON_BASEDN, ode); |
| | | } |
| | | } |
| | |
| | | } |
| | | } |
| | | } |
| | | String bindDn = getBindDN(ctx.getLdapContext()); |
| | | String pwd = getBindPassword(ctx.getLdapContext()); |
| | | String bindDn = getBindDN(conn.getLdapContext()); |
| | | String pwd = getBindPassword(conn.getLdapContext()); |
| | | for (ServerDescriptor s : serversToUpdate) |
| | | { |
| | | removeReferencesInServer(s, replicationServerHostPort, bindDn, pwd, |
| | | baseDNsToUpdate, disableReplicationServer, |
| | | getPreferredConnections(ctx.getLdapContext())); |
| | | getPreferredConnections(conn)); |
| | | } |
| | | |
| | | if (disableReplicationServer) |
| | | { |
| | | // Disable replication server |
| | | disableReplicationServer(ctx); |
| | | disableReplicationServer(conn); |
| | | replicationServerDisabled = true; |
| | | // Wait to be sure that changes are taken into account and reset the |
| | | // contents of the ADS. |
| | |
| | | if (disableReplicationServer && !replicationServerDisabled) |
| | | { |
| | | // This can happen if we could not retrieve the TopologyCache |
| | | disableReplicationServer(ctx); |
| | | disableReplicationServer(conn); |
| | | replicationServerDisabled = true; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Displays the replication status of the different base DNs in the servers |
| | | * registered in the ADS. |
| | | * @param ctx the connection to the server. |
| | | * @param uData the StatusReplicationUserData object containing the required |
| | | * parameters to update the configuration. |
| | | * @throws ReplicationCliException if there is an error. |
| | | * Displays the replication status of the different base DNs in the servers registered in the ADS. |
| | | * |
| | | * @param conn |
| | | * the connection to the server. |
| | | * @param uData |
| | | * the StatusReplicationUserData object containing the required parameters to update the |
| | | * configuration. |
| | | * @throws ReplicationCliException |
| | | * if there is an error. |
| | | */ |
| | | private void displayStatus(ConnectionWrapper ctx, |
| | | private void displayStatus(ConnectionWrapper conn, |
| | | StatusReplicationUserData uData) throws ReplicationCliException |
| | | { |
| | | ADSContext adsCtx = new ADSContext(ctx); |
| | | ADSContext adsCtx = new ADSContext(conn); |
| | | |
| | | boolean somethingDisplayed = false; |
| | | TopologyCache cache; |
| | | try |
| | | { |
| | | cache = new TopologyCache(adsCtx, getTrustManager(sourceServerCI), getConnectTimeout()); |
| | | cache.setPreferredConnections(getPreferredConnections(ctx.getLdapContext())); |
| | | cache.setPreferredConnections(getPreferredConnections(conn)); |
| | | addBaseDNs(cache.getFilter(), uData.getBaseDNs()); |
| | | cache.reloadTopology(); |
| | | } |
| | |
| | | } |
| | | if (!rServers.isEmpty()) |
| | | { |
| | | displayStatus(rServers, uData.isScriptFriendly(), getPreferredConnections(ctx.getLdapContext())); |
| | | displayStatus(rServers, uData.isScriptFriendly(), getPreferredConnections(conn)); |
| | | somethingDisplayed = true; |
| | | } |
| | | } |
| | |
| | | boolean inserted = false; |
| | | for (int i=0; i<orderedReplicaLists.size() && !inserted; i++) |
| | | { |
| | | String dn2 = |
| | | orderedReplicaLists.get(i).iterator().next().getSuffix().getDN(); |
| | | String dn2 = orderedReplicaLists.get(i).iterator().next().getSuffix().getDN(); |
| | | if (dn1.compareTo(dn2) < 0) |
| | | { |
| | | orderedReplicaLists.add(i, replicas); |
| | |
| | | Set<ReplicaDescriptor> replicasWithNoReplicationServer = new HashSet<>(); |
| | | Set<ServerDescriptor> serversWithNoReplica = new HashSet<>(); |
| | | displayStatus(orderedReplicaLists, uData.isScriptFriendly(), |
| | | getPreferredConnections(ctx.getLdapContext()), |
| | | cache.getServers(), |
| | | getPreferredConnections(conn), cache.getServers(), |
| | | replicasWithNoReplicationServer, serversWithNoReplica); |
| | | somethingDisplayed = true; |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * Updates the configuration of the replication server with the list of |
| | | * replication servers provided. |
| | | * @param ctx the context connected to the server that we want to update. |
| | | * @param replicationServers the list of replication servers to which the |
| | | * replication server will communicate with. |
| | | * @throws OpenDsException if there is an error updating the configuration. |
| | | * Updates the configuration of the replication server with the list of replication servers |
| | | * provided. |
| | | * |
| | | * @param conn |
| | | * the connection to the server that we want to update. |
| | | * @param replicationServers |
| | | * the list of replication servers to which the replication server will communicate with. |
| | | * @throws OpenDsException |
| | | * if there is an error updating the configuration. |
| | | */ |
| | | private void updateReplicationServer(ConnectionWrapper ctx, |
| | | private void updateReplicationServer(ConnectionWrapper conn, |
| | | Set<String> replicationServers) throws Exception |
| | | { |
| | | print(formatter.getFormattedWithPoints( |
| | | INFO_REPLICATION_ENABLE_UPDATING_REPLICATION_SERVER.get(ctx.getHostPort()))); |
| | | INFO_REPLICATION_ENABLE_UPDATING_REPLICATION_SERVER.get(conn.getHostPort()))); |
| | | |
| | | RootCfgClient root = ctx.getRootConfiguration(); |
| | | RootCfgClient root = conn.getRootConfiguration(); |
| | | |
| | | ReplicationSynchronizationProviderCfgClient sync = |
| | | (ReplicationSynchronizationProviderCfgClient) |
| | |
| | | } |
| | | |
| | | /** |
| | | * Configures a replication domain for a given base DN in the server to which |
| | | * the provided InitialLdapContext is connected. |
| | | * @param ctx the context connected to the server that we want to configure. |
| | | * @param baseDN the base DN of the replication domain to configure. |
| | | * @param replicationServers the list of replication servers to which the |
| | | * replication domain will communicate with. |
| | | * @param usedReplicationDomainIds the set of replication domain IDs that |
| | | * are already in use. The set will be updated with the replication ID |
| | | * that will be used by the newly configured replication server. |
| | | * @throws OpenDsException if there is an error updating the configuration. |
| | | * Configures a replication domain for a given base DN in the server for which the connection is |
| | | * provided. |
| | | * |
| | | * @param conn |
| | | * the connection to the server that we want to configure. |
| | | * @param baseDN |
| | | * the base DN of the replication domain to configure. |
| | | * @param replicationServers |
| | | * the list of replication servers to which the replication domain will communicate with. |
| | | * @param usedReplicationDomainIds |
| | | * the set of replication domain IDs that are already in use. The set will be updated |
| | | * with the replication ID that will be used by the newly configured replication server. |
| | | * @throws OpenDsException |
| | | * if there is an error updating the configuration. |
| | | */ |
| | | private void configureToReplicateBaseDN(ConnectionWrapper ctx, |
| | | private void configureToReplicateBaseDN(ConnectionWrapper conn, |
| | | String baseDN, |
| | | Set<String> replicationServers, |
| | | Set<Integer> usedReplicationDomainIds) throws Exception |
| | |
| | | && areDnsEqual(baseDN, ADSContext.getAdministrationSuffixDN())) |
| | | { |
| | | print(formatter.getFormattedWithPoints( |
| | | INFO_REPLICATION_ENABLE_CONFIGURING_ADS.get(ctx.getHostPort()))); |
| | | INFO_REPLICATION_ENABLE_CONFIGURING_ADS.get(conn.getHostPort()))); |
| | | } |
| | | else |
| | | { |
| | | print(formatter.getFormattedWithPoints( |
| | | INFO_REPLICATION_ENABLE_CONFIGURING_BASEDN.get(baseDN, ctx.getHostPort()))); |
| | | INFO_REPLICATION_ENABLE_CONFIGURING_BASEDN.get(baseDN, conn.getHostPort()))); |
| | | } |
| | | RootCfgClient root = ctx.getRootConfiguration(); |
| | | |
| | | RootCfgClient root = conn.getRootConfiguration(); |
| | | ReplicationSynchronizationProviderCfgClient sync = |
| | | (ReplicationSynchronizationProviderCfgClient) |
| | | root.getSynchronizationProvider("Multimaster Synchronization"); |
| | |
| | | for (ServerDescriptor s : allServers) |
| | | { |
| | | logger.info(LocalizableMessage.raw("Configuring server "+server.getHostPort(true))); |
| | | try (ConnectionWrapper conn = getDirContextForServer(cache, s)) |
| | | try (ConnectionWrapper conn = getConnection(cache, s)) |
| | | { |
| | | if (serversToConfigureDomain.contains(s)) |
| | | { |
| | |
| | | return adminProperties; |
| | | } |
| | | |
| | | private void initializeSuffix(String baseDN, InitialLdapContext ctxSource, |
| | | InitialLdapContext ctxDestination, boolean displayProgress) |
| | | private void initializeSuffix(String baseDN, ConnectionWrapper connSource, ConnectionWrapper connDestination, |
| | | boolean displayProgress) |
| | | throws ReplicationCliException |
| | | { |
| | | int replicationId = -1; |
| | |
| | | TopologyCacheFilter filter = new TopologyCacheFilter(); |
| | | filter.setSearchMonitoringInformation(false); |
| | | filter.addBaseDNToSearch(baseDN); |
| | | ServerDescriptor source = ServerDescriptor.createStandalone(ctxSource, filter); |
| | | ServerDescriptor source = ServerDescriptor.createStandalone(connSource.getLdapContext(), filter); |
| | | for (ReplicaDescriptor replica : source.getReplicas()) |
| | | { |
| | | if (areDnsEqual(replica.getSuffix().getDN(), baseDN)) |
| | |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | | LocalizableMessage msg = getMessageForException(ne, getHostPort(ctxSource).toString()); |
| | | LocalizableMessage msg = getMessageForException(ne, connSource.getHostPort().toString()); |
| | | throw new ReplicationCliException(msg, ERROR_READING_CONFIGURATION, ne); |
| | | } |
| | | |
| | | if (replicationId == -1) |
| | | { |
| | | throw new ReplicationCliException( |
| | | ERR_INITIALIZING_REPLICATIONID_NOT_FOUND.get(getHostPort(ctxSource), baseDN), |
| | | ERR_INITIALIZING_REPLICATIONID_NOT_FOUND.get(connSource.getHostPort(), baseDN), |
| | | REPLICATIONID_NOT_FOUND, null); |
| | | } |
| | | |
| | |
| | | { |
| | | try |
| | | { |
| | | installer.initializeSuffix(ctxDestination, replicationId, baseDN, displayProgress, getHostPort(ctxSource)); |
| | | installer.initializeSuffix( |
| | | connDestination.getLdapContext(), replicationId, baseDN, displayProgress, connSource.getHostPort()); |
| | | initDone = true; |
| | | } |
| | | catch (PeerNotFoundException pnfe) |
| | |
| | | /** |
| | | * Initializes all the replicas in the topology with the contents of a |
| | | * given replica. |
| | | * @param ctx the connection to the server where the source replica of the |
| | | * @param conn the connection to the server where the source replica of the |
| | | * initialization is. |
| | | * @param baseDN the dn of the suffix. |
| | | * @param displayProgress whether we want to display progress or not. |
| | | * @throws ReplicationCliException if an unexpected error occurs. |
| | | */ |
| | | public void initializeAllSuffix(String baseDN, InitialLdapContext ctx, boolean displayProgress) |
| | | public void initializeAllSuffix(String baseDN, ConnectionWrapper conn, boolean displayProgress) |
| | | throws ReplicationCliException |
| | | { |
| | | if (argParser == null) |
| | |
| | | { |
| | | try |
| | | { |
| | | initializeAllSuffixTry(baseDN, ctx, displayProgress); |
| | | postPreExternalInitialization(baseDN, ctx, false); |
| | | initializeAllSuffixTry(baseDN, conn, displayProgress); |
| | | postPreExternalInitialization(baseDN, conn, false); |
| | | initDone = true; |
| | | } |
| | | catch (PeerNotFoundException pnfe) |
| | |
| | | * Launches the pre external initialization operation using the provided |
| | | * connection on a given base DN. |
| | | * @param baseDN the base DN that we want to reset. |
| | | * @param ctx the connection to the server. |
| | | * @param conn the connection to the server. |
| | | * @throws ReplicationCliException if there is an error performing the |
| | | * operation. |
| | | */ |
| | | private void preExternalInitialization(String baseDN, InitialLdapContext ctx) throws ReplicationCliException |
| | | private void preExternalInitialization(String baseDN, ConnectionWrapper conn) throws ReplicationCliException |
| | | { |
| | | postPreExternalInitialization(baseDN, ctx, true); |
| | | postPreExternalInitialization(baseDN, conn, true); |
| | | } |
| | | |
| | | /** |
| | | * Launches the post external initialization operation using the provided |
| | | * connection on a given base DN required for replication to work. |
| | | * @param baseDN the base DN that we want to reset. |
| | | * @param ctx the connection to the server. |
| | | * @param conn the connection to the server. |
| | | * @throws ReplicationCliException if there is an error performing the |
| | | * operation. |
| | | */ |
| | | private void postExternalInitialization(String baseDN, InitialLdapContext ctx) throws ReplicationCliException |
| | | private void postExternalInitialization(String baseDN, ConnectionWrapper conn) throws ReplicationCliException |
| | | { |
| | | postPreExternalInitialization(baseDN, ctx, false); |
| | | postPreExternalInitialization(baseDN, conn, false); |
| | | } |
| | | |
| | | /** |
| | | * Launches the pre or post external initialization operation using the |
| | | * provided connection on a given base DN. |
| | | * @param baseDN the base DN that we want to reset. |
| | | * @param ctx the connection to the server. |
| | | * @param conn the connection to the server. |
| | | * @param isPre whether this is the pre operation or the post operation. |
| | | * @throws ReplicationCliException if there is an error performing the |
| | | * operation. |
| | | * @throws ReplicationCliException if there is an error performing the operation |
| | | */ |
| | | private void postPreExternalInitialization(String baseDN, |
| | | InitialLdapContext ctx, boolean isPre) throws ReplicationCliException |
| | | ConnectionWrapper conn, boolean isPre) throws ReplicationCliException |
| | | { |
| | | boolean isOver = false; |
| | | String dn = null; |
| | |
| | | attrMap.put("ds-task-reset-generation-id-domain-base-dn", baseDN); |
| | | |
| | | try { |
| | | dn = createServerTask(ctx, "ds-task-reset-generation-id", "org.opends.server.tasks.SetGenerationIdTask", |
| | | "dsreplication-reset-generation-id", attrMap); |
| | | dn = createServerTask(conn, |
| | | "ds-task-reset-generation-id", |
| | | "org.opends.server.tasks.SetGenerationIdTask", |
| | | "dsreplication-reset-generation-id", |
| | | attrMap); |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | |
| | | sleepCatchInterrupt(500); |
| | | try |
| | | { |
| | | SearchResult sr = getLastSearchResult(ctx, dn, "ds-task-log-message", "ds-task-state"); |
| | | SearchResult sr = getLastSearchResult(conn, dn, "ds-task-log-message", "ds-task-state"); |
| | | String logMsg = getFirstValue(sr, "ds-task-log-message"); |
| | | if (logMsg != null && !logMsg.equals(lastLogMsg)) |
| | | { |
| | |
| | | if (helper.isDone(state) || helper.isStoppedByError(state)) |
| | | { |
| | | isOver = true; |
| | | LocalizableMessage errorMsg = getPrePostErrorMsg(lastLogMsg, state, ctx); |
| | | LocalizableMessage errorMsg = getPrePostErrorMsg(lastLogMsg, state, conn); |
| | | |
| | | if (helper.isCompletedWithErrors(state)) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | private LocalizableMessage getPrePostErrorMsg(String lastLogMsg, String state, InitialLdapContext ctx) |
| | | private LocalizableMessage getPrePostErrorMsg(String lastLogMsg, String state, ConnectionWrapper conn) |
| | | { |
| | | HostPort server = getHostPort(ctx); |
| | | HostPort hostPort = conn.getHostPort(); |
| | | if (lastLogMsg != null) |
| | | { |
| | | return ERR_UNEXPECTED_DURING_TASK_WITH_LOG.get(lastLogMsg, state, server); |
| | | return ERR_UNEXPECTED_DURING_TASK_WITH_LOG.get(lastLogMsg, state, hostPort); |
| | | } |
| | | return ERR_UNEXPECTED_DURING_TASK_NO_LOG.get(state, server); |
| | | return ERR_UNEXPECTED_DURING_TASK_NO_LOG.get(state, hostPort); |
| | | } |
| | | |
| | | private void sleepCatchInterrupt(long millis) |
| | |
| | | /** |
| | | * Initializes all the replicas in the topology with the contents of a |
| | | * given replica. This method will try to create the task only once. |
| | | * @param ctx the connection to the server where the source replica of the |
| | | * @param conn the connection to the server where the source replica of the |
| | | * initialization is. |
| | | * @param baseDN the dn of the suffix. |
| | | * @param displayProgress whether we want to display progress or not. |
| | |
| | | * @throws PeerNotFoundException if the replication mechanism cannot find |
| | | * a peer. |
| | | */ |
| | | public void initializeAllSuffixTry(String baseDN, InitialLdapContext ctx, |
| | | boolean displayProgress) |
| | | throws ClientException, PeerNotFoundException |
| | | public void initializeAllSuffixTry(String baseDN, ConnectionWrapper conn, boolean displayProgress) |
| | | throws ClientException, PeerNotFoundException |
| | | { |
| | | boolean isOver = false; |
| | | String dn = null; |
| | | HostPort serverDisplay = getHostPort(ctx); |
| | | HostPort hostPort = conn.getHostPort(); |
| | | Map<String, String> attrsMap = new TreeMap<>(); |
| | | attrsMap.put("ds-task-initialize-domain-dn", baseDN); |
| | | attrsMap.put("ds-task-initialize-replica-server-id", "all"); |
| | | try |
| | | { |
| | | dn = createServerTask(ctx, "ds-task-initialize-remote-replica", "org.opends.server.tasks.InitializeTargetTask", |
| | | "dsreplication-initialize", attrsMap); |
| | | dn = createServerTask(conn, |
| | | "ds-task-initialize-remote-replica", |
| | | "org.opends.server.tasks.InitializeTargetTask", |
| | | "dsreplication-initialize", |
| | | attrsMap); |
| | | } |
| | | catch (NamingException ne) |
| | | { |
| | | throw new ClientException(ReturnCode.APPLICATION_ERROR, |
| | | getThrowableMsg(INFO_ERROR_LAUNCHING_INITIALIZATION.get(serverDisplay), ne), ne); |
| | | getThrowableMsg(INFO_ERROR_LAUNCHING_INITIALIZATION.get(hostPort), ne), ne); |
| | | } |
| | | |
| | | LocalizableMessage lastDisplayedMsg = null; |
| | |
| | | sleepCatchInterrupt(500); |
| | | try |
| | | { |
| | | SearchResult sr = getLastSearchResult(ctx, dn, "ds-task-unprocessed-entry-count", |
| | | SearchResult sr = getLastSearchResult(conn, dn, "ds-task-unprocessed-entry-count", |
| | | "ds-task-processed-entry-count", "ds-task-log-message", "ds-task-state" ); |
| | | |
| | | // Get the number of entries that have been handled and a percentage... |
| | |
| | | println(); |
| | | } |
| | | |
| | | LocalizableMessage errorMsg = getInitializeAllErrorMsg(serverDisplay, lastLogMsg, state); |
| | | LocalizableMessage errorMsg = getInitializeAllErrorMsg(hostPort, lastLogMsg, state); |
| | | if (helper.isCompletedWithErrors(state)) |
| | | { |
| | | logger.warn(LocalizableMessage.raw("Processed errorMsg: "+errorMsg)); |
| | |
| | | { |
| | | throw new ClientException( |
| | | ReturnCode.APPLICATION_ERROR, |
| | | getThrowableMsg(INFO_ERROR_POOLING_INITIALIZATION.get( |
| | | serverDisplay), ne), ne); |
| | | getThrowableMsg(INFO_ERROR_POOLING_INITIALIZATION.get(hostPort), ne), ne); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private SearchResult getLastSearchResult(InitialLdapContext ctx, String dn, String... returnedAttributes) |
| | | private SearchResult getLastSearchResult(ConnectionWrapper conn, String dn, String... returnedAttributes) |
| | | throws NamingException |
| | | { |
| | | SearchControls searchControls = new SearchControls(); |
| | | searchControls.setSearchScope(SearchControls.OBJECT_SCOPE); |
| | | searchControls.setReturningAttributes(returnedAttributes); |
| | | NamingEnumeration<SearchResult> res = ctx.search(dn, "objectclass=*", searchControls); |
| | | NamingEnumeration<SearchResult> res = conn.getLdapContext().search(dn, "objectclass=*", searchControls); |
| | | try |
| | | { |
| | | SearchResult sr = null; |
| | |
| | | } |
| | | } |
| | | |
| | | private String createServerTask(InitialLdapContext ctx, String taskObjectclass, |
| | | private String createServerTask(ConnectionWrapper conn, String taskObjectclass, |
| | | String taskJavaClass, String taskID, Map<String, String> taskAttrs) throws NamingException |
| | | { |
| | | int i = 1; |
| | |
| | | dn = "ds-task-id=" + id + ",cn=Scheduled Tasks,cn=Tasks"; |
| | | try |
| | | { |
| | | DirContext dirCtx = ctx.createSubcontext(dn, attrs); |
| | | DirContext dirCtx = conn.getLdapContext().createSubcontext(dn, attrs); |
| | | logger.info(LocalizableMessage.raw("created task entry: " + attrs)); |
| | | dirCtx.close(); |
| | | return dn; |
| | |
| | | filter.setSearchBaseDNInformation(false); |
| | | ServerLoader loader = new ServerLoader(server.getAdsProperties(), bindDn, |
| | | pwd, getTrustManager(sourceServerCI), getConnectTimeout(), cnx, filter); |
| | | ConnectionWrapper ctx = null; |
| | | String lastBaseDN = null; |
| | | HostPort hostPort = null; |
| | | |
| | | try |
| | | try (ConnectionWrapper conn = loader.createConnectionWrapper()) |
| | | { |
| | | ctx = loader.createConnectionWrapper(); |
| | | hostPort = ctx.getHostPort(); |
| | | RootCfgClient root = ctx.getRootConfiguration(); |
| | | hostPort = conn.getHostPort(); |
| | | RootCfgClient root = conn.getRootConfiguration(); |
| | | ReplicationSynchronizationProviderCfgClient sync = null; |
| | | try |
| | | { |
| | |
| | | throw new ReplicationCliException(msg, ERROR_CONNECTING, ode); |
| | | } |
| | | } |
| | | finally |
| | | { |
| | | close(ctx); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | * @return <CODE>true</CODE> if we want to disable all the replicated suffixes |
| | | * and <CODE>false</CODE> otherwise. |
| | | */ |
| | | private boolean disableAllBaseDns(InitialLdapContext ctx, |
| | | DisableReplicationUserData uData) |
| | | private boolean disableAllBaseDns(ConnectionWrapper conn, DisableReplicationUserData uData) |
| | | { |
| | | if (uData.disableAll()) |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | Collection<ReplicaDescriptor> replicas = getReplicas(ctx); |
| | | Collection<ReplicaDescriptor> replicas = getReplicas(conn); |
| | | Set<String> replicatedSuffixes = new HashSet<>(); |
| | | for (ReplicaDescriptor rep : replicas) |
| | | { |
| | |
| | | } |
| | | |
| | | private void updateAvailableAndReplicatedSuffixesForOneDomain( |
| | | ConnectionWrapper ctxDomain, ConnectionWrapper ctxOther, |
| | | ConnectionWrapper connDomain, ConnectionWrapper connOther, |
| | | Set<String> availableSuffixes, Set<String> alreadyReplicatedSuffixes) |
| | | { |
| | | Collection<ReplicaDescriptor> replicas = getReplicas(ctxDomain.getLdapContext()); |
| | | int replicationPort = getReplicationPort(ctxOther); |
| | | Collection<ReplicaDescriptor> replicas = getReplicas(connDomain); |
| | | int replicationPort = getReplicationPort(connOther); |
| | | boolean isReplicationServerConfigured = replicationPort != -1; |
| | | String replicationServer = getReplicationServer(ctxOther.getHostPort().getHost(), replicationPort); |
| | | String replicationServer = getReplicationServer(connOther.getHostPort().getHost(), replicationPort); |
| | | for (ReplicaDescriptor replica : replicas) |
| | | { |
| | | if (!isReplicationServerConfigured) |
| | |
| | | } |
| | | |
| | | private void updateAvailableAndReplicatedSuffixesForNoDomain( |
| | | ConnectionWrapper ctx1, ConnectionWrapper ctx2, |
| | | ConnectionWrapper conn1, ConnectionWrapper conn2, |
| | | Set<String> availableSuffixes, Set<String> alreadyReplicatedSuffixes) |
| | | { |
| | | int replicationPort1 = getReplicationPort(ctx1); |
| | | int replicationPort1 = getReplicationPort(conn1); |
| | | boolean isReplicationServer1Configured = replicationPort1 != -1; |
| | | String replicationServer1 = getReplicationServer(ctx1.getHostPort().getHost(), replicationPort1); |
| | | String replicationServer1 = getReplicationServer(conn1.getHostPort().getHost(), replicationPort1); |
| | | |
| | | int replicationPort2 = getReplicationPort(ctx2); |
| | | int replicationPort2 = getReplicationPort(conn2); |
| | | boolean isReplicationServer2Configured = replicationPort2 != -1; |
| | | String replicationServer2 = getReplicationServer(ctx2.getHostPort().getHost(), replicationPort2); |
| | | String replicationServer2 = getReplicationServer(conn2.getHostPort().getHost(), replicationPort2); |
| | | |
| | | TopologyCache cache1 = isReplicationServer1Configured ? createTopologyCache(ctx1) : null; |
| | | TopologyCache cache2 = isReplicationServer2Configured ? createTopologyCache(ctx2) : null; |
| | | TopologyCache cache1 = isReplicationServer1Configured ? createTopologyCache(conn1) : null; |
| | | TopologyCache cache2 = isReplicationServer2Configured ? createTopologyCache(conn2) : null; |
| | | if (cache1 != null && cache2 != null) |
| | | { |
| | | updateAvailableAndReplicatedSuffixesForNoDomainOneSense(cache1, cache2, |
| | |
| | | } |
| | | } |
| | | |
| | | private TopologyCache createTopologyCache(ConnectionWrapper ctx) |
| | | private TopologyCache createTopologyCache(ConnectionWrapper conn) |
| | | { |
| | | try |
| | | { |
| | | ADSContext adsContext = new ADSContext(ctx); |
| | | ADSContext adsContext = new ADSContext(conn); |
| | | if (adsContext.hasAdminData()) |
| | | { |
| | | TopologyCache cache = new TopologyCache(adsContext, getTrustManager(sourceServerCI), getConnectTimeout()); |
| | | cache.getFilter().setSearchMonitoringInformation(false); |
| | | cache.setPreferredConnections(getPreferredConnections(ctx.getLdapContext())); |
| | | cache.setPreferredConnections(getPreferredConnections(conn)); |
| | | cache.reloadTopology(); |
| | | return cache; |
| | | } |
| | |
| | | catch (Throwable t) |
| | | { |
| | | logger.warn(LocalizableMessage.raw("Error loading topology cache in " |
| | | + getLdapUrl(ctx.getLdapContext()) + ": " + t, t)); |
| | | + getLdapUrl(conn.getLdapContext()) + ": " + t, t)); |
| | | } |
| | | return null; |
| | | } |
| | |
| | | } |
| | | |
| | | private void updateAvailableAndReplicatedSuffixesForNoDomainOneSense( |
| | | TopologyCache cache1, TopologyCache cache2, String replicationServer1, |
| | | String replicationServer2, |
| | | TopologyCache cache1, TopologyCache cache2, String replicationServer1, String replicationServer2, |
| | | Set<String> availableSuffixes, Set<String> alreadyReplicatedSuffixes) |
| | | { |
| | | for (SuffixDescriptor suffix : cache1.getSuffixes()) |
| | |
| | | PointAdder pointAdder = new PointAdder(this); |
| | | try |
| | | { |
| | | Set<PreferredConnection> cnx = new LinkedHashSet<>(getPreferredConnections(adsCtx1.getDirContext())); |
| | | cnx.addAll(getPreferredConnections(adsCtx2.getDirContext())); |
| | | Set<PreferredConnection> cnx = new LinkedHashSet<>(getPreferredConnections(adsCtx1.getConnection())); |
| | | cnx.addAll(getPreferredConnections(adsCtx2.getConnection())); |
| | | TopologyCache cache1 = createTopologyCache(adsCtx1, cnx); |
| | | TopologyCache cache2 = createTopologyCache(adsCtx2, cnx); |
| | | |
| | |
| | | { |
| | | logger.info(LocalizableMessage.raw("Seeding to replication server on "+ |
| | | server.getHostPort(true)+" with certificates of "+ adsCtxSource.getHostPort())); |
| | | try (ConnectionWrapper conn = getDirContextForServer(cacheDestination, server)) |
| | | try (ConnectionWrapper conn = getConnection(cacheDestination, server)) |
| | | { |
| | | ServerDescriptor.seedAdsTrustStore(conn.getLdapContext(), adsCtxSource.getTrustedCertificates()); |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | private ConnectionWrapper getDirContextForServer(TopologyCache cache, ServerDescriptor server) |
| | | throws NamingException |
| | | private ConnectionWrapper getConnection(TopologyCache cache, ServerDescriptor server) throws NamingException |
| | | { |
| | | String dn = getBindDN(cache.getAdsContext().getDirContext()); |
| | | String pwd = getBindPassword(cache.getAdsContext().getDirContext()); |