new HashMap<String, LinkedHashSet<String>>();
Set<Integer> usedReplicationServerIds = new HashSet<Integer>();
HashMap<String, Set<Integer>> hmUsedReplicationDomainIds =
new HashMap<String, Set<Integer>>();
ServerDescriptor server1;
TopologyCacheFilter filter = new TopologyCacheFilter();
filter.setSearchMonitoringInformation(false);
filter.addBaseDNToSearch(ADSContext.getAdministrationSuffixDN());
filter.addBaseDNToSearch(Constants.SCHEMA_DN);
for (String dn : uData.getBaseDNs())
{
filter.addBaseDNToSearch(dn);
}
try
{
server1 = ServerDescriptor.createStandalone(ctx1, filter);
}
catch (NamingException ne)
{
throw new ReplicationCliException(
getMessageForException(ne, ConnectionUtils.getHostPort(ctx1)),
ERROR_READING_CONFIGURATION, ne);
}
ServerDescriptor server2;
try
{
server2 = ServerDescriptor.createStandalone(ctx2, filter);
}
catch (NamingException ne)
{
throw new ReplicationCliException(
getMessageForException(ne, ConnectionUtils.getHostPort(ctx2)),
ERROR_READING_CONFIGURATION, ne);
}
ADSContext adsCtx1 = new ADSContext(ctx1);
ADSContext adsCtx2 = new ADSContext(ctx2);
if (!argParser.isInteractive())
{
// Inform the user of the potential errors that we found in the already
// registered servers.
LinkedHashSet<Message> messages = new LinkedHashSet<Message>();
try
{
LinkedHashSet<PreferredConnection> cnx =
new LinkedHashSet<PreferredConnection>();
cnx.addAll(PreferredConnection.getPreferredConnections(ctx1));
cnx.addAll(PreferredConnection.getPreferredConnections(ctx2));
if (adsCtx1.hasAdminData())
{
TopologyCache cache = new TopologyCache(adsCtx1, getTrustManager(),
getConnectTimeout());
cache.setPreferredConnections(cnx);
cache.getFilter().setSearchMonitoringInformation(false);
for (String dn : uData.getBaseDNs())
{
cache.getFilter().addBaseDNToSearch(dn);
}
cache.reloadTopology();
messages.addAll(cache.getErrorMessages());
}
if (adsCtx2.hasAdminData())
{
TopologyCache cache = new TopologyCache(adsCtx2, getTrustManager(),
getConnectTimeout());
cache.setPreferredConnections(cnx);
cache.getFilter().setSearchMonitoringInformation(false);
for (String dn : uData.getBaseDNs())
{
cache.getFilter().addBaseDNToSearch(dn);
}
cache.reloadTopology();
messages.addAll(cache.getErrorMessages());
}
}
catch (TopologyCacheException tce)
{
throw new ReplicationCliException(
ERR_REPLICATION_READING_ADS.get(tce.getMessage()),
ERROR_READING_TOPOLOGY_CACHE, tce);
}
catch (ADSContextException adce)
{
throw new ReplicationCliException(
ERR_REPLICATION_READING_ADS.get(adce.getMessage()),
ERROR_READING_ADS, adce);
}
if (!messages.isEmpty())
{
println(ERR_REPLICATION_READING_REGISTERED_SERVERS_WARNING.get(
Utils.getMessageFromCollection(messages,
Constants.LINE_SEPARATOR).toString()));
}
}
// Check whether there is more than one replication server in the
// topology.
Set<String> baseDNsWithOneReplicationServer = new TreeSet<String>();
Set<String> baseDNsWithNoReplicationServer = new TreeSet<String>();
updateBaseDnsWithNotEnoughReplicationServer(adsCtx1, adsCtx2, uData,
baseDNsWithNoReplicationServer, baseDNsWithOneReplicationServer);
if (!baseDNsWithNoReplicationServer.isEmpty())
{
Message errorMsg =
ERR_REPLICATION_NO_REPLICATION_SERVER.get(
Utils.getStringFromCollection(baseDNsWithNoReplicationServer,
Constants.LINE_SEPARATOR));
throw new ReplicationCliException(
errorMsg,
ReplicationCliReturnCode.ERROR_USER_DATA, null);
}
else if (!baseDNsWithOneReplicationServer.isEmpty())
{
if (isInteractive())
{
Message confirmMsg =
INFO_REPLICATION_ONLY_ONE_REPLICATION_SERVER_CONFIRM.get(
Utils.getStringFromCollection(baseDNsWithOneReplicationServer,
Constants.LINE_SEPARATOR));
try
{
if (!confirmAction(confirmMsg, false))
{
throw new ReplicationCliException(
ERR_REPLICATION_USER_CANCELLED.get(),
ReplicationCliReturnCode.USER_CANCELLED, null);
}
}
catch (Throwable t)
{
throw new ReplicationCliException(
ERR_REPLICATION_USER_CANCELLED.get(),
ReplicationCliReturnCode.USER_CANCELLED, t);
}
}
else
{
Message warningMsg =
INFO_REPLICATION_ONLY_ONE_REPLICATION_SERVER_WARNING.get(
Utils.getStringFromCollection(baseDNsWithOneReplicationServer,
Constants.LINE_SEPARATOR));
println(warningMsg);
println();
}
}
// These are used to identify which server we use to initialize
// the contents of the other server (if any).
InitialLdapContext ctxSource = null;
InitialLdapContext ctxDestination = null;
ADSContext adsCtxSource = null;
boolean adsAlreadyReplicated = false;
boolean adsMergeDone = false;
printProgress(formatter.getFormattedWithPoints(
INFO_REPLICATION_ENABLE_UPDATING_ADS_CONTENTS.get()));
try
{
if (adsCtx1.hasAdminData() && adsCtx2.hasAdminData())
{
Set<Map<ADSContext.ServerProperty, Object>> registry1 =
adsCtx1.readServerRegistry();
Set<Map<ADSContext.ServerProperty, Object>> registry2 =
adsCtx2.readServerRegistry();
if (registry2.size() <= 1)
{
if (!hasAdministrator(adsCtx1.getDirContext(), uData))
{
adsCtx1.createAdministrator(getAdministratorProperties(uData));
}
server2.updateAdsPropertiesWithServerProperties();
registerServer(adsCtx1, server2.getAdsProperties());
if (!ADSContext.isRegistered(server1, registry1))
{
server1.updateAdsPropertiesWithServerProperties();
registerServer(adsCtx1, server1.getAdsProperties());
}
ctxSource = ctx1;
ctxDestination = ctx2;
adsCtxSource = adsCtx1;
}
else if (registry1.size() <= 1)
{
if (!hasAdministrator(adsCtx2.getDirContext(), uData))
{
adsCtx2.createAdministrator(getAdministratorProperties(uData));
}
server1.updateAdsPropertiesWithServerProperties();
registerServer(adsCtx2, server1.getAdsProperties());
if (!ADSContext.isRegistered(server2, registry2))
{
server2.updateAdsPropertiesWithServerProperties();
registerServer(adsCtx2, server2.getAdsProperties());
}
ctxSource = ctx2;
ctxDestination = ctx1;
adsCtxSource = adsCtx2;
}
else if (!areEqual(registry1, registry2))
{
printProgress(formatter.getFormattedDone());
printlnProgress();
boolean isFirstSource = mergeRegistries(adsCtx1, adsCtx2);
if (isFirstSource)
{
ctxSource = ctx1;
}
else
{
ctxSource = ctx2;
}
adsMergeDone = true;
}
else
{
// They are already replicated: nothing to do in terms of ADS
// initialization or ADS update data
adsAlreadyReplicated = isBaseDNReplicated(server1, server2,
ADSContext.getAdministrationSuffixDN());
if (!adsAlreadyReplicated)
{
// Try to merge if both are replicated
boolean isADS1Replicated = isBaseDNReplicated(server1,
ADSContext.getAdministrationSuffixDN());
boolean isADS2Replicated = isBaseDNReplicated(server2,
ADSContext.getAdministrationSuffixDN());
if (isADS1Replicated && isADS2Replicated)
{
// Merge
printProgress(formatter.getFormattedDone());
printlnProgress();
boolean isFirstSource = mergeRegistries(adsCtx1, adsCtx2);
if (isFirstSource)
{
ctxSource = ctx1;
}
else
{
ctxSource = ctx2;
}
adsMergeDone = true;
}
else if (isADS1Replicated || !isADS2Replicated)
{
// The case where only the first ADS is replicated or none
// is replicated.
if (!hasAdministrator(adsCtx1.getDirContext(), uData))
{
adsCtx1.createAdministrator(getAdministratorProperties(uData));
}
server2.updateAdsPropertiesWithServerProperties();
registerServer(adsCtx1, server2.getAdsProperties());
if (!ADSContext.isRegistered(server1, registry1))
{
server1.updateAdsPropertiesWithServerProperties();
registerServer(adsCtx1, server1.getAdsProperties());
}
ctxSource = ctx1;
ctxDestination = ctx2;
adsCtxSource = adsCtx1;
}
else if (isADS2Replicated)
{
if (!hasAdministrator(adsCtx2.getDirContext(), uData))
{
adsCtx2.createAdministrator(getAdministratorProperties(uData));
}
server1.updateAdsPropertiesWithServerProperties();
registerServer(adsCtx2, server1.getAdsProperties());
if (!ADSContext.isRegistered(server2, registry2))
{
server2.updateAdsPropertiesWithServerProperties();
registerServer(adsCtx2, server2.getAdsProperties());
}
ctxSource = ctx2;
ctxDestination = ctx1;
adsCtxSource = adsCtx2;
}
}
}
}
else if (!adsCtx1.hasAdminData() && adsCtx2.hasAdminData())
{
// adsCtx1.createAdministrationSuffix(null);
if (!hasAdministrator(adsCtx2.getDirContext(), uData))
{
adsCtx2.createAdministrator(getAdministratorProperties(uData));
}
server1.updateAdsPropertiesWithServerProperties();
registerServer(adsCtx2, server1.getAdsProperties());
Set<Map<ADSContext.ServerProperty, Object>> registry2 =
adsCtx2.readServerRegistry();
if (!ADSContext.isRegistered(server2, registry2))
{
server2.updateAdsPropertiesWithServerProperties();
registerServer(adsCtx2, server2.getAdsProperties());
}
ctxSource = ctx2;
ctxDestination = ctx1;
adsCtxSource = adsCtx2;
}
else if (adsCtx1.hasAdminData() && !adsCtx2.hasAdminData())
{
// adsCtx2.createAdministrationSuffix(null);
if (!hasAdministrator(adsCtx1.getDirContext(), uData))
{
adsCtx1.createAdministrator(getAdministratorProperties(uData));
}
server2.updateAdsPropertiesWithServerProperties();
registerServer(adsCtx1, server2.getAdsProperties());
Set<Map<ADSContext.ServerProperty, Object>> registry1 =
adsCtx1.readServerRegistry();
if (!ADSContext.isRegistered(server1, registry1))
{
server1.updateAdsPropertiesWithServerProperties();
registerServer(adsCtx1, server1.getAdsProperties());
}
ctxSource = ctx1;
ctxDestination = ctx2;
adsCtxSource = adsCtx1;
}
else
{
adsCtx1.createAdminData(null);
if (!hasAdministrator(ctx1, uData))
{
// This could occur if the user created an administrator without
// registering any server.
adsCtx1.createAdministrator(getAdministratorProperties(uData));
}
server1.updateAdsPropertiesWithServerProperties();
adsCtx1.registerServer(server1.getAdsProperties());
server2.updateAdsPropertiesWithServerProperties();
adsCtx1.registerServer(server2.getAdsProperties());
// adsCtx2.createAdministrationSuffix(null);
ctxSource = ctx1;
ctxDestination = ctx2;
adsCtxSource = adsCtx1;
}
}
catch (ADSContextException adce)
{
throw new ReplicationCliException(
ERR_REPLICATION_UPDATING_ADS.get(adce.getMessageObject()),
ERROR_UPDATING_ADS, adce);
}
if (!adsAlreadyReplicated && !adsMergeDone)
{
try
{
ServerDescriptor.seedAdsTrustStore(ctxDestination,
adsCtxSource.getTrustedCertificates());
}
catch (Throwable t)
{
LOG.log(Level.SEVERE, "Error seeding truststores: "+t, t);
String arg = (t instanceof OpenDsException) ?
((OpenDsException)t).getMessageObject().toString() : t.toString();
throw new ReplicationCliException(
ERR_REPLICATION_ENABLE_SEEDING_TRUSTSTORE.get(
ConnectionUtils.getHostPort(ctxDestination),
ConnectionUtils.getHostPort(adsCtxSource.getDirContext()),
arg),
ERROR_SEEDING_TRUSTORE, t);
}
}
if (!adsMergeDone)
{
printProgress(formatter.getFormattedDone());
printlnProgress();
}
LinkedList<String> baseDNs = uData.getBaseDNs();
if (!adsAlreadyReplicated)
{
boolean found = false;
for (String dn : baseDNs)
{
if (Utils.areDnsEqual(dn, ADSContext.getAdministrationSuffixDN()))
{
found = true;
break;
}
}
if (!found)
{
baseDNs.add(ADSContext.getAdministrationSuffixDN());
uData.setBaseDNs(baseDNs);
}
}
if (uData.replicateSchema())
{
baseDNs = uData.getBaseDNs();
baseDNs.add(Constants.SCHEMA_DN);
uData.setBaseDNs(baseDNs);
}
TopologyCache cache1 = null;
TopologyCache cache2 = null;
try
{
LinkedHashSet<PreferredConnection> cnx =
new LinkedHashSet<PreferredConnection>();
cnx.addAll(PreferredConnection.getPreferredConnections(ctx1));
cnx.addAll(PreferredConnection.getPreferredConnections(ctx2));
if (adsCtx1.hasAdminData())
{
cache1 = new TopologyCache(adsCtx1, getTrustManager(),
getConnectTimeout());
cache1.setPreferredConnections(cnx);
cache1.getFilter().setSearchMonitoringInformation(false);
for (String dn : uData.getBaseDNs())
{
cache1.getFilter().addBaseDNToSearch(dn);
}
cache1.reloadTopology();
usedReplicationServerIds.addAll(getReplicationServerIds(cache1));
}
if (adsCtx2.hasAdminData())
{
cache2 = new TopologyCache(adsCtx2, getTrustManager(),
getConnectTimeout());
cache2.setPreferredConnections(cnx);
cache2.getFilter().setSearchMonitoringInformation(false);
for (String dn : uData.getBaseDNs())
{
cache2.getFilter().addBaseDNToSearch(dn);
}
cache2.reloadTopology();
usedReplicationServerIds.addAll(getReplicationServerIds(cache2));
}
}
catch (ADSContextException adce)
{
throw new ReplicationCliException(
ERR_REPLICATION_READING_ADS.get(adce.getMessage()),
ERROR_READING_ADS, adce);
}
catch (TopologyCacheException tce)
{
throw new ReplicationCliException(
ERR_REPLICATION_READING_ADS.get(tce.getMessage()),
ERROR_READING_TOPOLOGY_CACHE, tce);
}
if (server1.isReplicationServer())
{
twoReplServers.add(server1.getReplicationServerHostPort());
usedReplicationServerIds.add(server1.getReplicationServerId());
}
else if (uData.configureReplicationServer1())
{
twoReplServers.add(getReplicationServer(
ConnectionUtils.getHostName(ctx1), uData.getReplicationPort1()));
}
if (server2.isReplicationServer())
{
twoReplServers.add(server2.getReplicationServerHostPort());
usedReplicationServerIds.add(server2.getReplicationServerId());
}
else if (uData.configureReplicationServer2())
{
twoReplServers.add(getReplicationServer(
ConnectionUtils.getHostName(ctx2), uData.getReplicationPort2()));
}
for (String baseDN : uData.getBaseDNs())
{
LinkedHashSet<String> repServersForBaseDN = new LinkedHashSet<String>();
repServersForBaseDN.addAll(getReplicationServers(baseDN, cache1,
server1));
repServersForBaseDN.addAll(getReplicationServers(baseDN, cache2,
server2));
repServersForBaseDN.addAll(twoReplServers);
hmRepServers.put(baseDN, repServersForBaseDN);
Set<Integer> ids = new HashSet<Integer>();
ids.addAll(getReplicationDomainIds(baseDN, server1));
ids.addAll(getReplicationDomainIds(baseDN, server2));
if (cache1 != null)
{
for (ServerDescriptor server : cache1.getServers())
{
ids.addAll(getReplicationDomainIds(baseDN, server));
}
}
if (cache2 != null)
{
for (ServerDescriptor server : cache2.getServers())
{
ids.addAll(getReplicationDomainIds(baseDN, server));
}
}
hmUsedReplicationDomainIds.put(baseDN, ids);
}
for (LinkedHashSet<String> v : hmRepServers.values())
{
allRepServers.addAll(v);
}
Set<String> alreadyConfiguredReplicationServers = new HashSet<String>();
if (!server1.isReplicationServer() && uData.configureReplicationServer1())
{
try
{
configureAsReplicationServer(ctx1, uData.getReplicationPort1(),
uData.isSecureReplication1(), allRepServers,
usedReplicationServerIds);
}
catch (OpenDsException ode)
{
throw new ReplicationCliException(
getMessageForReplicationServerException(ode,
ConnectionUtils.getHostPort(ctx1)),
ERROR_CONFIGURING_REPLICATIONSERVER, ode);
}
}
else if (server1.isReplicationServer())
{
try
{
updateReplicationServer(ctx1, allRepServers);
}
catch (OpenDsException ode)
{
throw new ReplicationCliException(
getMessageForReplicationServerException(ode,
ConnectionUtils.getHostPort(ctx1)),
ERROR_CONFIGURING_REPLICATIONSERVER, ode);
}
if (argParser.replicationPort1Arg.isPresent())
{
// Inform the user that the provided value will be ignored
if (uData.getReplicationPort1() !=
server1.getReplicationServerPort())
{
LOG.log(Level.WARNING, "Ignoring provided replication port for "+
"first server (already configured with port "+
server1.getReplicationServerPort()+")");
println(WARN_FIRST_REPLICATION_SERVER_ALREADY_CONFIGURED.get(
server1.getReplicationServerPort(), uData.getReplicationPort1()));
}
}
}
alreadyConfiguredReplicationServers.add(server1.getId());
if (!server2.isReplicationServer() && uData.configureReplicationServer2())
{
try
{
configureAsReplicationServer(ctx2, uData.getReplicationPort2(),
uData.isSecureReplication2(), allRepServers,
usedReplicationServerIds);
}
catch (OpenDsException ode)
{
throw new ReplicationCliException(
getMessageForReplicationServerException(ode,
ConnectionUtils.getHostPort(ctx1)),
ERROR_CONFIGURING_REPLICATIONSERVER, ode);
}
}
else if (server2.isReplicationServer())
{
try
{
updateReplicationServer(ctx2, allRepServers);
}
catch (OpenDsException ode)
{
throw new ReplicationCliException(
getMessageForReplicationServerException(ode,
ConnectionUtils.getHostPort(ctx1)),
ERROR_CONFIGURING_REPLICATIONSERVER, ode);
}
if (argParser.replicationPort2Arg.isPresent())
{
// Inform the user that the provided value will be ignored
if (uData.getReplicationPort2() !=
server2.getReplicationServerPort())
{
LOG.log(Level.WARNING, "Ignoring provided replication port for "+
"second server (already configured with port "+
server2.getReplicationServerPort()+")");
println(WARN_SECOND_REPLICATION_SERVER_ALREADY_CONFIGURED.get(
server2.getReplicationServerPort(), uData.getReplicationPort2()));
}
}
}
alreadyConfiguredReplicationServers.add(server2.getId());
for (String baseDN : uData.getBaseDNs())
{
LinkedHashSet<String> repServers = hmRepServers.get(baseDN);
Set<Integer> usedIds = hmUsedReplicationDomainIds.get(baseDN);
Set<String> alreadyConfiguredServers = new HashSet<String>();
if (uData.configureReplicationDomain1() ||
Utils.areDnsEqual(baseDN, ADSContext.getAdministrationSuffixDN()))
{
try
{
configureToReplicateBaseDN(ctx1, baseDN, repServers, usedIds);
}
catch (OpenDsException ode)
{
Message msg = getMessageForEnableException(ode,
ConnectionUtils.getHostPort(ctx1), baseDN);
throw new ReplicationCliException(msg,
ERROR_ENABLING_REPLICATION_ON_BASEDN, ode);
}
}
alreadyConfiguredServers.add(server1.getId());
if (uData.configureReplicationDomain2() ||
Utils.areDnsEqual(baseDN, ADSContext.getAdministrationSuffixDN()))
{
try
{
configureToReplicateBaseDN(ctx2, baseDN, repServers, usedIds);
}
catch (OpenDsException ode)
{
Message msg = getMessageForEnableException(ode,
ConnectionUtils.getHostPort(ctx2), baseDN);
throw new ReplicationCliException(msg,
ERROR_ENABLING_REPLICATION_ON_BASEDN, ode);
}
}
alreadyConfiguredServers.add(server2.getId());
if (cache1 != null)
{
configureToReplicateBaseDN(baseDN, repServers, usedIds, cache1, server1,
alreadyConfiguredServers, allRepServers,