From 43e9c7913fc664b725e167090fe6d389a4558315 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Fri, 08 Jun 2007 14:43:45 +0000
Subject: [PATCH] The following commit adds all the code necessary to be able to configure replication using the setup.
---
opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java | 442 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 414 insertions(+), 28 deletions(-)
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java b/opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java
index 15ab091..7ee27c9 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/InstallerHelper.java
@@ -29,26 +29,67 @@
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import javax.naming.ldap.InitialLdapContext;
import org.opends.quicksetup.ApplicationException;
import org.opends.quicksetup.i18n.ResourceProvider;
import org.opends.quicksetup.webstart.JnlpProperties;
import org.opends.quicksetup.util.Utils;
+import org.opends.server.admin.DefaultBehaviorException;
+import org.opends.server.admin.ManagedObjectNotFoundException;
+import org.opends.server.admin.client.ManagementContext;
+import org.opends.server.admin.client.ldap.LDAPManagementContext;
+import org.opends.server.admin.client.ldap.JNDIDirContextAdaptor;
+import org.opends.server.admin.std.client.*;
+import org.opends.server.admin.std.meta.*;
+import org.opends.server.backends.task.TaskState;
+import org.opends.server.core.DirectoryServer;
+import org.opends.server.extensions.ConfigFileHandler;
+import org.opends.server.messages.CoreMessages;
+import org.opends.server.messages.ReplicationMessages;
+import org.opends.server.tools.ConfigureDS;
+import org.opends.server.tools.ConfigureWindowsService;
+import org.opends.server.tools.ImportLDIF;
+import org.opends.server.types.Attribute;
+import org.opends.server.types.AttributeType;
+import org.opends.server.types.AttributeValue;
+import org.opends.server.types.DN;
+import org.opends.server.types.DirectoryException;
+import org.opends.server.types.Entry;
+import org.opends.server.types.ExistingFileBehavior;
+import org.opends.server.types.LDIFExportConfig;
+import org.opends.server.types.ObjectClass;
+import org.opends.server.util.LDIFException;
+import org.opends.server.util.LDIFWriter;
+import org.opends.server.util.StaticUtils;
/**
* This is the only class that uses classes in org.opends.server (excluding the
- * case of org.opends.server.util.DynamicConstants and
- * org.opends.server.util.SetupUtils which are already included in
- * quicksetup.jar).
+ * case of DynamicConstants, SetupUtils, OperatingSystem and CertificateManager
+ * which are already included in quicksetup.jar).
*
- * Important note: do not include references to the classes in package
- * org.opends.server in the import. These classes must be loaded during
- * Runtime.
+ * Important note: do not include references to this class until OpenDS.jar has
+ * been loaded. These classes must be loaded during Runtime.
* The code is written in a way that when we execute the code that uses these
* classes the required jar files are already loaded. However these jar files
* are not necessarily loaded when we create this class.
*/
public class InstallerHelper implements JnlpProperties {
+ private static final Logger LOG = Logger.getLogger(
+ InstallerHelper.class.getName());
+
+ private static final int MAX_ID_VALUE = Short.MAX_VALUE;
+ private static final String DOMAIN_BASE_NAME = "domain ";
/**
* Invokes the method ConfigureDS.configMain with the provided parameters.
@@ -58,7 +99,7 @@
* @see org.opends.server.tools.ConfigureDS#configMain(String[]).
*/
public int invokeConfigureServer(String[] args) throws ApplicationException {
- return org.opends.server.tools.ConfigureDS.configMain(args);
+ return ConfigureDS.configMain(args);
}
/**
@@ -69,7 +110,7 @@
* @see org.opends.server.tools.ImportLDIF#mainImportLDIF(String[]).
*/
public int invokeImportLDIF(String[] args) throws ApplicationException {
- return org.opends.server.tools.ImportLDIF.mainImportLDIF(args);
+ return ImportLDIF.mainImportLDIF(args);
}
/**
@@ -78,8 +119,7 @@
*/
public String getStartedId()
{
- return String.valueOf(org.opends.server.messages.CoreMessages.
- MSGID_DIRECTORY_SERVER_STARTED);
+ return String.valueOf(CoreMessages.MSGID_DIRECTORY_SERVER_STARTED);
}
/**
@@ -87,18 +127,16 @@
* @throws ApplicationException if something goes wrong.
*/
public void enableWindowsService() throws ApplicationException {
- int code = org.opends.server.tools.ConfigureWindowsService.enableService(
- System.out, System.err);
+ int code = ConfigureWindowsService.enableService(System.out, System.err);
- String errorMessage = ResourceProvider.getInstance().getMsg(
- "error-enabling-windows-service");
+ String errorMessage = getMsg("error-enabling-windows-service");
switch (code) {
case
- org.opends.server.tools.ConfigureWindowsService.SERVICE_ENABLE_SUCCESS:
+ ConfigureWindowsService.SERVICE_ENABLE_SUCCESS:
break;
case
- org.opends.server.tools.ConfigureWindowsService.SERVICE_ALREADY_ENABLED:
+ ConfigureWindowsService.SERVICE_ALREADY_ENABLED:
break;
default:
throw new ApplicationException(
@@ -141,26 +179,21 @@
try
{
- org.opends.server.types.LDIFExportConfig exportConfig =
- new org.opends.server.types.LDIFExportConfig(ldifFile
- .getAbsolutePath(),
- org.opends.server.types.ExistingFileBehavior.OVERWRITE);
+ LDIFExportConfig exportConfig = new LDIFExportConfig(
+ ldifFile.getAbsolutePath(), ExistingFileBehavior.OVERWRITE);
- org.opends.server.util.LDIFWriter writer =
- new org.opends.server.util.LDIFWriter(exportConfig);
+ LDIFWriter writer = new LDIFWriter(exportConfig);
- org.opends.server.types.DN dn =
- org.opends.server.types.DN.decode(baseDn);
- org.opends.server.types.Entry entry =
- org.opends.server.util.StaticUtils.createEntry(dn);
+ DN dn = DN.decode(baseDn);
+ Entry entry = StaticUtils.createEntry(dn);
writer.writeEntry(entry);
writer.close();
- } catch (org.opends.server.types.DirectoryException de) {
+ } catch (DirectoryException de) {
throw new ApplicationException(
ApplicationException.Type.CONFIGURATION_ERROR,
getThrowableMsg("error-importing-ldif", null, de), de);
- } catch (org.opends.server.util.LDIFException le) {
+ } catch (LDIFException le) {
throw new ApplicationException(
ApplicationException.Type.CONFIGURATION_ERROR,
getThrowableMsg("error-importing-ldif", null, le), le);
@@ -175,4 +208,357 @@
}
return ldifFile;
}
+
+ /**
+ * Configures the replication on a given server.
+ * @param remoteCtx the conection to the server where we want to configure
+ * the replication.
+ * @param dns the suffix base dns for which we want to configure the
+ * replication.
+ * @param replicationServers a Map where the key value is the base dn and
+ * the value is the list of replication servers for that base dn (or domain).
+ * @param replicationPort the replicationPort of the server that is being
+ * configured (it might not exist and the user specified it in the setup).
+ * @param serverDisplay the server display.
+ * @param usedReplicationServerIds the list of replication server ids that
+ * are already used.
+ * @param usedServerIds the list of server ids (domain ids) that
+ * are already used.
+ * @throws ApplicationException if something goes wrong.
+ */
+ public void configureReplication(InitialLdapContext remoteCtx,
+ Set<String> dns, Map<String,Set<String>> replicationServers,
+ int replicationPort, String serverDisplay,
+ Set<Integer> usedReplicationServerIds, Set<Integer> usedServerIds)
+ throws ApplicationException
+ {
+ try
+ {
+ ManagementContext mCtx = LDAPManagementContext.createFromContext(
+ JNDIDirContextAdaptor.adapt(remoteCtx));
+ RootCfgClient root = mCtx.getRootConfiguration();
+
+ /*
+ * Configure Synchronization plugin.
+ */
+ MultimasterSynchronizationProviderCfgClient sync = null;
+ try
+ {
+ sync = (MultimasterSynchronizationProviderCfgClient)
+ root.getSynchronizationProvider("Multimaster Synchronization");
+ }
+ catch (ManagedObjectNotFoundException monfe)
+ {
+ // It does not exist.
+ }
+ if (sync == null)
+ {
+ MultimasterSynchronizationProviderCfgDefn provider =
+ MultimasterSynchronizationProviderCfgDefn.getInstance();
+ sync = root.createSynchronizationProvider(provider,
+ "Multimaster Synchronization",
+ new ArrayList<DefaultBehaviorException>());
+ sync.setJavaImplementationClass(
+ "org.opends.server.replication.plugin.MultimasterReplication");
+ }
+ sync.setEnabled(Boolean.TRUE);
+ sync.commit();
+
+ /*
+ * Configure the replication server.
+ */
+ ReplicationServerCfgClient replicationServer = null;
+
+ if (!sync.hasReplicationServer())
+ {
+ int id = getReplicationId(usedReplicationServerIds);
+ usedReplicationServerIds.add(id);
+ replicationServer = sync.createReplicationServer(
+ ReplicationServerCfgDefn.getInstance(),
+ new ArrayList<DefaultBehaviorException>());
+ replicationServer.setReplicationServerId(id);
+ replicationServer.setReplicationPort(replicationPort);
+ }
+ else
+ {
+ replicationServer = sync.getReplicationServer();
+ usedReplicationServerIds.add(
+ replicationServer.getReplicationServerId());
+ }
+
+ Set<String> servers = replicationServer.getReplicationServer();
+ if (servers == null)
+ {
+ servers = new HashSet<String>();
+ }
+ for (Set<String> rs : replicationServers.values())
+ {
+ servers.addAll(rs);
+ }
+
+ replicationServer.setReplicationServer(servers);
+
+ replicationServer.commit();
+
+ /*
+ * Create the domains
+ */
+ String[] domainNames = sync.listMultimasterDomains();
+ if (domainNames == null)
+ {
+ domainNames = new String[]{};
+ }
+ MultimasterDomainCfgClient[] domains =
+ new MultimasterDomainCfgClient[domainNames.length];
+ for (int i=0; i<domains.length; i++)
+ {
+ domains[i] = sync.getMultimasterDomain(domainNames[i]);
+ }
+ for (String dn : dns)
+ {
+ MultimasterDomainCfgClient domain = null;
+ for (int i=0; i<domains.length && (domain == null); i++)
+ {
+ if (Utils.areDnsEqual(dn,
+ domains[i].getReplicationDN().toString()))
+ {
+ domain = domains[i];
+ }
+ }
+ if (domain == null)
+ {
+ int domainId = getReplicationId(usedServerIds);
+ usedServerIds.add(domainId);
+ String domainName = getDomainName(domainNames, domainId);
+ domain = sync.createMultimasterDomain(
+ MultimasterDomainCfgDefn.getInstance(), domainName,
+ new ArrayList<DefaultBehaviorException>());
+ domain.setServerId(domainId);
+ domain.setReplicationDN(DN.decode(dn));
+ }
+ domain.setReplicationServer(replicationServers.get(dn));
+ usedServerIds.add(domain.getServerId());
+
+ domain.commit();
+ }
+ }
+ catch (Throwable t)
+ {
+ String errorMessage = getMsg("error-configuring-remote-generic",
+ serverDisplay, t.toString());
+ throw new ApplicationException(
+ ApplicationException.Type.CONFIGURATION_ERROR, errorMessage, t);
+ }
+ }
+
+ /**
+ * For the given state provided by a Task tells if the task is done or not.
+ * @param sState the String representing the task state.
+ * @return <CODE>true</CODE> if the task is done and <CODE>false</CODE>
+ * otherwise.
+ */
+ public boolean isDone(String sState)
+ {
+ TaskState state = TaskState.fromString(sState);
+ return TaskState.isDone(state);
+ }
+
+ /**
+ * For the given state provided by a Task tells if the task is successful or
+ * not.
+ * @param sState the String representing the task state.
+ * @return <CODE>true</CODE> if the task is successful and <CODE>false</CODE>
+ * otherwise.
+ */
+ public boolean isSuccessful(String sState)
+ {
+ TaskState state = TaskState.fromString(sState);
+ return TaskState.isSuccessful(state);
+ }
+
+ /**
+ * For the given state provided by a Task tells if the task is complete with
+ * errors or not.
+ * @param sState the String representing the task state.
+ * @return <CODE>true</CODE> if the task is complete with errors and
+ * <CODE>false</CODE> otherwise.
+ */
+ public boolean isCompletedWithErrors(String sState)
+ {
+ TaskState state = TaskState.fromString(sState);
+ return state == TaskState.COMPLETED_WITH_ERRORS;
+ }
+
+ /**
+ * For the given state provided by a Task tells if the task is stopped by
+ * error or not.
+ * @param sState the String representing the task state.
+ * @return <CODE>true</CODE> if the task is stopped by error and
+ * <CODE>false</CODE> otherwise.
+ */
+ public boolean isStoppedByError(String sState)
+ {
+ TaskState state = TaskState.fromString(sState);
+ return state == TaskState.STOPPED_BY_ERROR;
+ }
+
+ /**
+ * Tells whether the provided log message corresponds to a peers not found
+ * error during the initialization of a replica or not.
+ * @param logMsg the log message.
+ * @return <CODE>true</CODE> if the log message corresponds to a peers not
+ * found error during initialization and <CODE>false</CODE> otherwise.
+ */
+ public boolean isPeersNotFoundError(String logMsg)
+ {
+ return logMsg.indexOf(
+ "="+ReplicationMessages.MSGID_NO_REACHABLE_PEER_IN_THE_DOMAIN) != -1;
+ }
+ private void addConfigEntry(ConfigFileHandler configFileHandler, DN dn,
+ String[] ocs, String[] attributeNames, String[][] attributeValues)
+ throws DirectoryException
+ {
+ HashMap<ObjectClass,String> objectClasses =
+ new HashMap<ObjectClass,String>();
+ HashMap<AttributeType,List<Attribute>> userAttributes =
+ new HashMap<AttributeType,List<Attribute>>();
+ HashMap<AttributeType,List<Attribute>> operationalAttributes =
+ new HashMap<AttributeType,List<Attribute>>();
+
+ for (int j=0; j<ocs.length; j++)
+ {
+ String ocName = ocs[j];
+ ObjectClass objectClass = DirectoryServer.getObjectClass(ocName);
+ if (objectClass == null)
+ {
+ objectClass = DirectoryServer.getDefaultObjectClass(ocName);
+ }
+ objectClasses.put(objectClass, ocName);
+ }
+ for (int j=0; j<attributeNames.length; j++)
+ {
+ String attrName = attributeNames[j];
+ AttributeType attrType = DirectoryServer.getAttributeType(attrName);
+ if (attrType == null)
+ {
+ attrType = DirectoryServer.getDefaultAttributeType(attrName);
+ }
+ String[] attrValues = attributeValues[j];
+ LinkedHashSet<AttributeValue> valueSet =
+ new LinkedHashSet<AttributeValue>();
+ for (int k=0; k<attrValues.length; k++)
+ {
+ AttributeValue attributeValue = new AttributeValue(attrType,
+ attrValues[k]);
+ valueSet.add(attributeValue);
+ }
+ ArrayList<Attribute> attrList = new ArrayList<Attribute>();
+ attrList.add(new Attribute(attrType, attrName, null, valueSet));
+ userAttributes.put(attrType, attrList);
+ }
+ Entry entry = new Entry(dn, objectClasses, userAttributes,
+ operationalAttributes);
+ configFileHandler.addEntry(entry, null);
+ }
+
+ private int getReplicationId(Set<Integer> usedIds)
+ {
+ Random r = new Random();
+ int id = 0;
+ while ((id == 0) || usedIds.contains(id))
+ {
+ id = r.nextInt(MAX_ID_VALUE);
+ }
+ return id;
+ }
+
+ private String getMsg(String key, String ... args)
+ {
+ return ResourceProvider.getInstance().getMsg(key, args);
+ }
+
+ private String getDomainName(String[] existingDomains, int newDomainId)
+ {
+ String domainName = DOMAIN_BASE_NAME+newDomainId;
+ boolean nameExists = true;
+ int j = 0;
+ while (nameExists)
+ {
+ boolean found = false;
+ for (int i=0; i<existingDomains.length && !found; i++)
+ {
+ found = existingDomains[i].equalsIgnoreCase(domainName);
+ }
+ if (found)
+ {
+ domainName = DOMAIN_BASE_NAME+newDomainId+"-"+j;
+ }
+ else
+ {
+ nameExists = false;
+ }
+ j++;
+ }
+ return domainName;
+ }
}
+
+/**
+ * A class describing a replication domain.
+ *
+ */
+class DomainEntry
+{
+ private String name;
+ private int replicationId;
+ private String baseDn;
+ private Set<String> replicationServers;
+ /**
+ * The constructor of the domain entry.
+ * @param name the name of the domain.
+ * @param replicationId the replicationId of the domain.
+ * @param baseDn the base dn of the domain.
+ * @param replicationServers the list of replication servers for the domain.
+ */
+ public DomainEntry(String name, int replicationId, String baseDn,
+ Set<String> replicationServers)
+ {
+ this.name = name;
+ this.replicationId = replicationId;
+ this.baseDn = baseDn;
+ this.replicationServers = replicationServers;
+ }
+ /**
+ * Returns the base dn of the domain.
+ * @return the base dn of the domain.
+ */
+ public String getBaseDn()
+ {
+ return baseDn;
+ }
+ /**
+ * Returns the name of the domain.
+ * @return the name of the domain.
+ */
+ public String getName()
+ {
+ return name;
+ }
+ /**
+ * Returns the replication Id of the domain.
+ * @return the replication Id of the domain.
+ */
+ public int getReplicationId()
+ {
+ return replicationId;
+ }
+ /**
+ * Returns the list of replication servers of the domain.
+ * @return the list of replication servers of the domain.
+ */
+ public Set<String> getReplicationServers()
+ {
+ return replicationServers;
+ }
+}
+
--
Gitblit v1.10.0