* the registries.
*/
private boolean mergeRegistries(ADSContext adsCtx1, ADSContext adsCtx2)
throws ReplicationCliException
{
PointAdder pointAdder = new PointAdder(this);
try
{
LinkedHashSet<PreferredConnection> cnx =
new LinkedHashSet<PreferredConnection>();
cnx.addAll(PreferredConnection.getPreferredConnections(
adsCtx1.getDirContext()));
cnx.addAll(PreferredConnection.getPreferredConnections(
adsCtx2.getDirContext()));
// Check that there are no errors. We do not allow to do the merge with
// errors.
TopologyCache cache1 = new TopologyCache(adsCtx1, getTrustManager(),
getConnectTimeout());
cache1.setPreferredConnections(cnx);
cache1.getFilter().setSearchBaseDNInformation(false);
try
{
cache1.reloadTopology();
}
catch (TopologyCacheException te)
{
LOG.log(Level.SEVERE, "Error reading topology cache of "+
ConnectionUtils.getHostPort(adsCtx1.getDirContext())+ " "+te, te);
throw new ReplicationCliException(
ERR_REPLICATION_READING_ADS.get(te.getMessageObject()),
ERROR_UPDATING_ADS, te);
}
TopologyCache cache2 = new TopologyCache(adsCtx2, getTrustManager(),
getConnectTimeout());
cache2.setPreferredConnections(cnx);
cache2.getFilter().setSearchBaseDNInformation(false);
try
{
cache2.reloadTopology();
}
catch (TopologyCacheException te)
{
LOG.log(Level.SEVERE, "Error reading topology cache of "+
ConnectionUtils.getHostPort(adsCtx2.getDirContext())+ " "+te, te);
throw new ReplicationCliException(
ERR_REPLICATION_READING_ADS.get(te.getMessageObject()),
ERROR_UPDATING_ADS, te);
}
// Look for the cache with biggest number of replication servers:
// that one is going to be source.
int nRepServers1 = 0;
for (ServerDescriptor server : cache1.getServers())
{
if (server.isReplicationServer())
{
nRepServers1 ++;
}
}
int nRepServers2 = 0;
for (ServerDescriptor server : cache2.getServers())
{
if (server.isReplicationServer())
{
nRepServers2 ++;
}
}
InitialLdapContext ctxSource;
InitialLdapContext ctxDestination;
if (nRepServers1 >= nRepServers2)
{
ctxSource = adsCtx1.getDirContext();
ctxDestination = adsCtx2.getDirContext();
}
else
{
ctxSource = adsCtx2.getDirContext();
ctxDestination = adsCtx1.getDirContext();
}
if (isInteractive())
{
Message msg = INFO_REPLICATION_MERGING_REGISTRIES_CONFIRMATION.get(
ConnectionUtils.getHostPort(ctxSource),
ConnectionUtils.getHostPort(ctxDestination),
ConnectionUtils.getHostPort(ctxSource),
ConnectionUtils.getHostPort(ctxDestination));
try
{
if (!askConfirmation(msg, true, LOG))
{
throw new ReplicationCliException(
ERR_REPLICATION_USER_CANCELLED.get(),
ReplicationCliReturnCode.USER_CANCELLED, null);
}
}
catch (CLIException ce)
{
println(ce.getMessageObject());
throw new ReplicationCliException(
ERR_REPLICATION_USER_CANCELLED.get(),
ReplicationCliReturnCode.USER_CANCELLED, null);
}
}
else
{
Message msg = INFO_REPLICATION_MERGING_REGISTRIES_DESCRIPTION.get(
ConnectionUtils.getHostPort(ctxSource),
ConnectionUtils.getHostPort(ctxDestination),
ConnectionUtils.getHostPort(ctxSource),
ConnectionUtils.getHostPort(ctxDestination));
println(msg);
println();
}
printProgress(INFO_REPLICATION_MERGING_REGISTRIES_PROGRESS.get());
pointAdder.start();
Collection<Message> cache1Errors = cache1.getErrorMessages();
if (!cache1Errors.isEmpty())
{
throw new ReplicationCliException(
ERR_REPLICATION_CANNOT_MERGE_WITH_ERRORS.get(
ConnectionUtils.getHostPort(adsCtx1.getDirContext()),
Utils.getMessageFromCollection(cache1Errors,
Constants.LINE_SEPARATOR)),
ERROR_READING_ADS, null);
}
Collection<Message> cache2Errors = cache2.getErrorMessages();
if (!cache2Errors.isEmpty())
{
throw new ReplicationCliException(
ERR_REPLICATION_CANNOT_MERGE_WITH_ERRORS.get(
ConnectionUtils.getHostPort(adsCtx2.getDirContext()),
Utils.getMessageFromCollection(cache2Errors,
Constants.LINE_SEPARATOR)),
ERROR_READING_ADS, null);
}
Set<Message> commonRepServerIDErrors = new HashSet<Message>();
for (ServerDescriptor server1 : cache1.getServers())
{
if (server1.isReplicationServer())
{
int replicationID1 = server1.getReplicationServerId();
boolean found = false;
for (ServerDescriptor server2 : cache2.getServers())
{
if (server2.isReplicationServer())
{
int replicationID2 = server2.getReplicationServerId();
found = replicationID2 == replicationID1;
if (found)
{
commonRepServerIDErrors.add(
ERR_REPLICATION_ENABLE_COMMON_REPLICATION_SERVER_ID_ARG.get(
server1.getHostPort(true),
server2.getHostPort(true),
replicationID1));
found = true;
break;
}
}
}
if (found)
{
break;
}
}
}
Set<Message> commonDomainIDErrors = new HashSet<Message>();
for (SuffixDescriptor suffix1 : cache1.getSuffixes())
{
for (ReplicaDescriptor replica1 : suffix1.getReplicas())
{
if (replica1.isReplicated())
{
int domain1 = replica1.getReplicationId();
boolean found = false;
for (SuffixDescriptor suffix2 : cache2.getSuffixes())
{
if (!Utils.areDnsEqual(suffix2.getDN(),
replica1.getSuffix().getDN()))
{
// Conflicting domain names must apply to same suffix.
continue;
}
for (ReplicaDescriptor replica2 : suffix2.getReplicas())
{
if (replica2.isReplicated())
{
int domain2 = replica2.getReplicationId();
if (domain1 == domain2)
{
commonDomainIDErrors.add(
ERR_REPLICATION_ENABLE_COMMON_DOMAIN_ID_ARG.get(
replica1.getServer().getHostPort(true),
suffix1.getDN(),
replica2.getServer().getHostPort(true),
suffix2.getDN(),
domain1));
found = true;
break;
}
}
}
if (found)
{
break;
}
}
}
}
}
if (!commonRepServerIDErrors.isEmpty() || !commonDomainIDErrors.isEmpty())
{
MessageBuilder mb = new MessageBuilder();
if (!commonRepServerIDErrors.isEmpty())
{
mb.append(ERR_REPLICATION_ENABLE_COMMON_REPLICATION_SERVER_ID.get(
Utils.getMessageFromCollection(commonRepServerIDErrors,
Constants.LINE_SEPARATOR)));
}
if (!commonDomainIDErrors.isEmpty())
{
if (mb.length() > 0)
{
mb.append(Constants.LINE_SEPARATOR);
}
mb.append(ERR_REPLICATION_ENABLE_COMMON_DOMAIN_ID.get(
Utils.getMessageFromCollection(commonDomainIDErrors,
Constants.LINE_SEPARATOR)));
}
throw new ReplicationCliException(mb.toMessage(),
ReplicationCliReturnCode.REPLICATION_ADS_MERGE_NOT_SUPPORTED,
null);
}
ADSContext adsCtxSource;
ADSContext adsCtxDestination;
TopologyCache cacheDestination;
if (nRepServers1 >= nRepServers2)
{
adsCtxSource = adsCtx1;
adsCtxDestination = adsCtx2;
cacheDestination = cache2;
}
else
{
adsCtxSource = adsCtx2;
adsCtxDestination = adsCtx1;
cacheDestination = cache1;
}
try
{
adsCtxSource.mergeWithRegistry(adsCtxDestination);
}
catch (ADSContextException adce)
{
LOG.log(Level.SEVERE, "Error merging registry of "+
ConnectionUtils.getHostPort(adsCtxSource.getDirContext())+
" with registry of "+
ConnectionUtils.getHostPort(adsCtxDestination.getDirContext())+" "+
adce, adce);
if (adce.getError() == ADSContextException.ErrorType.ERROR_MERGING)
{
throw new ReplicationCliException(adce.getMessageObject(),
REPLICATION_ADS_MERGE_NOT_SUPPORTED, adce);
}
else
{
throw new ReplicationCliException(
ERR_REPLICATION_UPDATING_ADS.get(adce.getMessageObject()),
ERROR_UPDATING_ADS, adce);
}
}
try
{
for (ServerDescriptor server : cacheDestination.getServers())
{
if (server.isReplicationServer())
{
LOG.log(Level.INFO, "Seeding to replication server on "+
server.getHostPort(true)+" with certificates of "+
ConnectionUtils.getHostPort(adsCtxSource.getDirContext()));
InitialLdapContext ctx = null;
try
{
ctx = getDirContextForServer(cacheDestination, server);
ServerDescriptor.seedAdsTrustStore(ctx,
adsCtxSource.getTrustedCertificates());
}
finally
{
if (ctx != null)
{
ctx.close();
}
}
}
}
}
catch (Throwable t)
{
LOG.log(Level.SEVERE, "Error seeding truststore: "+t, t);
String arg = (t instanceof OpenDsException) ?
((OpenDsException)t).getMessageObject().toString() : t.toString();
throw new ReplicationCliException(
ERR_REPLICATION_ENABLE_SEEDING_TRUSTSTORE.get(
ConnectionUtils.getHostPort(adsCtx2.getDirContext()),
ConnectionUtils.getHostPort(adsCtx1.getDirContext()),
arg),
ERROR_SEEDING_TRUSTORE, t);
}
pointAdder.stop();
printProgress(formatter.getSpace());
printProgress(formatter.getFormattedDone());
printlnProgress();
return adsCtxSource == adsCtx1;
}
finally
{
pointAdder.stop();
}
}