Update the synchronization configuration to
- put changelog configuration below cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config
- use ds-cfg-changelog-server-id and ds-cfg-directory-server-id instead of ds-cfg-server-id
- don't require the ds-cfg-changelog-server attribute in changelog configuration (ds-cfg-synchronization-changelog-server-config objectclass)
Use dc=example,dc=com instead of dc=com in he synchronization configuration example
improve the javadoc
1 files deleted
2 files added
13 files modified
| | |
| | | ds-cfg-synchronization-provider-enabled: true |
| | | ds-cfg-synchronization-provider-class: org.opends.server.synchronization.MultimasterSynchronization |
| | | |
| | | dn: cn=com, cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config |
| | | dn: cn=example, cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config |
| | | objectClass: top |
| | | objectClass: ds-cfg-synchronization-provider-config |
| | | cn: com |
| | | ds-cfg-synchronization-dn: dc=com |
| | | cn: example |
| | | ds-cfg-synchronization-dn: dc=example,dc=com |
| | | ds-cfg-changelog-server: host1:8989 |
| | | ds-cfg-changelog-server: host2:8989 |
| | | ds-cfg-server-id: 1 |
| | | ds-cfg-directory-server-id: 1 |
| | | ds-cfg-receive-status: true |
| | | |
| | | dn: cn=Changelog Server, cn=config |
| | | dn: cn=Changelog Server, cn=Multimaster Synchronization, cn=Synchronization Providers, cn=config |
| | | objectClass: top |
| | | objectClass: ds-cfg-synchronization-changelog-server-config |
| | | cn: Changelog Server |
| | | ds-cfg-changelog-port: 8989 |
| | | ds-cfg-changelog-server: host1:8989 |
| | | ds-cfg-changelog-server: host2:8989 |
| | | ds-cfg-server-id: 1 |
| | | ds-cfg-changelog-server-id: 1 |
| | | |
| | |
| | | NAME 'ds-cfg-changelog-port' |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.26027.1.1.159 |
| | | NAME 'ds-cfg-server-id' |
| | | attributeTypes: ( 1.3.6.1.4.1.26027.1.1.278 |
| | | NAME 'ds-cfg-changelog-server-id' |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.26027.1.1.279 |
| | | NAME 'ds-cfg-directory-server-id' |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.26027.1.1.160 |
| | |
| | | ds-cfg-synchronization-provider-enabled ) X-ORIGIN 'OpenDS Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.58 NAME |
| | | 'ds-cfg-synchronization-provider-config' SUP top |
| | | STRUCTURAL MUST ( ds-cfg-changelog-server $ ds-cfg-server-id |
| | | STRUCTURAL MUST ( ds-cfg-changelog-server $ ds-cfg-directory-server-id |
| | | $ ds-cfg-synchronization-dn ) |
| | | MAY ( cn $ ds-cfg-receive-status $ ds-cfg-max-receive-queue $ |
| | | ds-cfg-max-receive-delay $ ds-cfg-max-send-queue $ ds-cfg-max-send-delay ) |
| | |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.65 NAME |
| | | 'ds-cfg-synchronization-changelog-server-config' SUP top |
| | | STRUCTURAL MUST (ds-cfg-server-id $ ds-cfg-changelog-port $ |
| | | ds-cfg-changelog-server ) MAY cn X-ORIGIN 'OpenDS Directory Server' ) |
| | | STRUCTURAL MUST (ds-cfg-changelog-server-id $ ds-cfg-changelog-port ) |
| | | MAY ( ds-cfg-changelog-server $ cn ) X-ORIGIN 'OpenDS Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.66 NAME 'ds-backup-directory' |
| | | SUP top STRUCTURAL MUST ( ds-backup-directory-path $ ds-backup-backend-dn ) |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | |
| | | new ArrayList<ConfigAttribute>(); |
| | | |
| | | static String CHANGELOG_SERVER_ATTR = "ds-cfg-changelog-server"; |
| | | static String SERVER_ID_ATTR = "ds-cfg-server-id"; |
| | | static String SERVER_ID_ATTR = "ds-cfg-changelog-server-id"; |
| | | static String CHANGELOG_PORT_ATTR = "ds-cfg-changelog-port"; |
| | | |
| | | /** |
| | |
| | | import org.opends.server.synchronization.SynchronizationMessage; |
| | | |
| | | /** |
| | | * This class Implement a protocol session using a basic socket and relying on |
| | | * the innate encoding/decoding capabilities of the SynchronizationMessage |
| | | * by using the getBytes() and generateMsg() methods of those classes. |
| | | * |
| | | * TODO : should have some versioning in the packets so that |
| | | * the futur versions can evolve while still |
| | | * being able to understand the older versions. |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Portions Copyright 2006 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | /** |
| | | * This package contains the code for the changelog service part |
| | | * of the Multimaster synchronization feature. |
| | | * <br> |
| | | * |
| | | * A changelog server is responsible for : |
| | | * <br> |
| | | * <ul> |
| | | * <li>listen for connections from ldap servers.</li> |
| | | * <li>Connect/manage connection to other changelog servers.</li> |
| | | * <li>Receive changes from ldap servers.</li> |
| | | * <li>Forward changes to ldap server and other changelog servers.</li> |
| | | * <li>Save changes to stable storage (includes trimming of older operations). |
| | | * </li> |
| | | * </ul> |
| | | * <br> |
| | | * The main classes of this packages are : |
| | | * <br> |
| | | * <ul> |
| | | * <li><A HREF="SocketSession.html"><B>SocketSession</B></A> |
| | | * implements the ProtocolSession interface that is |
| | | * used by the changelog server and the directory server to communicate. |
| | | * This is done by using the innate encoding/decoding capabilities of the |
| | | * SynchronizationMessages objects. This class is used by both the |
| | | * changelog and the synchronization package. |
| | | * </li> |
| | | * <li><A HREF="ChangelogCache.html"><B>ChangelogCache</B></A> |
| | | * implements the multiplexing part of the changelog |
| | | * server. It contains method for forwarding all the received messages to |
| | | * the ServerHandler and to the dbHandler objects.<br> |
| | | * </li> |
| | | * <li><A HREF="ServerHandler.html"><B>ServerHandler</B></A> |
| | | * contains the code related to handler of remote |
| | | * server. It can manage changelog servers of directory servers (may be it |
| | | * shoudl be splitted in two different classes, one for each of these).<br> |
| | | * </li> |
| | | * <li><A HREF="ServerWriter.html"><B>ServerWriter</B></A> |
| | | * the thread responsible for writing to the remote |
| | | * server.<br> |
| | | * </li> |
| | | * <li><A HREF="ServerReader.html"><B>ServerReader</B></A> |
| | | * the thread responsible for reading from the remote |
| | | * object.<br> |
| | | * </li> |
| | | * <li><A HREF="DbHandler.html"><B>DbHandler</B></A> |
| | | * DbHandler contains the code responsible for saving the changes to |
| | | * stable storage.<br> |
| | | * </li> |
| | | * </ul> |
| | | */ |
| | | |
| | | package org.opends.server.changelog; |
| | |
| | | import java.util.zip.DataFormatException; |
| | | |
| | | /** |
| | | * This Class is used to send acks between LDAP and changelog servers. |
| | | * Used to send acks between LDAP and changelog servers. |
| | | */ |
| | | public class AckMessage extends SynchronizationMessage implements Serializable |
| | | { |
| | |
| | | |
| | | /** |
| | | * This classes is used to store historical information. |
| | | * TODO : better explanation is needed |
| | | * One object of this type is created for each attribute that was changed in |
| | | * the entry. |
| | | * It allows to record the last time a givene value was added, the last |
| | | * time a given value was deleted and the last time the whole attribute was |
| | | * deleted. |
| | | */ |
| | | public class AttrInfo |
| | | { |
| | |
| | | |
| | | /** |
| | | * Used to store historical information. |
| | | * Contain a map of AttrInfo for each options of a given attribute type. |
| | | */ |
| | | public class AttrInfoWithOptions |
| | | { |
| | |
| | | |
| | | |
| | | /** |
| | | * The broker for synchronization based on a changelog system. |
| | | * The broker for Multimaster Synchronization. |
| | | */ |
| | | public class ChangelogBroker implements InternalSearchListener |
| | | { |
| | |
| | | Modification mod) |
| | | { |
| | | /* |
| | | * There is no need to check the historical information here |
| | | * The historical information will be updated in the pre-operation |
| | | * part of this plugin because this will allow to catch the changes |
| | | * that have been done by the plugins. |
| | | * The operation is either a non-conflicting operation or a local |
| | | * operation so there is no need to check the historical information |
| | | * for conflicts. |
| | | * If this is a local operation, the this code is run during |
| | | * the pre-operation phase (TODO : should make sure that synchronization |
| | | * is always run after all other plugins) |
| | | * If this is a non-conflicting replicated operation, this code is run |
| | | * during the handleConflictResolution(). |
| | | */ |
| | | |
| | | Attribute modAttr = mod.getAttribute(); |
| | |
| | | attrInfo = null; |
| | | |
| | | /* |
| | | * The following code only works for multi-valued attributes. |
| | | * TODO : See impact of single valued attributes |
| | | */ |
| | | if (attrInfo == null) |
| | |
| | | /* |
| | | * If this is a local operation we need first to update the historical |
| | | * information, then update the entry with the historical information |
| | | * IF this is a replicated operation the historical information has |
| | | * If this is a replicated operation the historical information has |
| | | * already been set in the resolveConflict phase and we only need |
| | | * to update the entry |
| | | */ |
| | |
| | | * for potential conflict |
| | | * @return true if there is a potential conflict, false otherwise |
| | | */ |
| | | public boolean hasConflict(AttrInfo info, ChangeNumber newChange) |
| | | private boolean hasConflict(AttrInfo info, ChangeNumber newChange) |
| | | { |
| | | // if I've already seen a newer change that the one |
| | | // if I've already seen a change that is more recetn than the one |
| | | // that is currently being processed, then there is |
| | | // a potential conflict |
| | | if (ChangeNumber.compare(newChange, moreRecentChangenumber) <= 0) |
| | |
| | | * This attribute is unknown from the schema |
| | | * Just skip it, the modification will be processed but no |
| | | * historical information is going to be kept. |
| | | * TODO : recovery tool should dela with this, add some logging. |
| | | * TODO : recovery tool should deal with this, add some logging. |
| | | */ |
| | | continue; |
| | | } |
| | |
| | | attrInfo.delete(cn); |
| | | break; |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | |
| | | /** |
| | | * This class is used to load the Synchronization code inside the JVM |
| | | * and to trigger initialization of the synchronization. |
| | | * |
| | | * It also extends the SynchronizationProvider class in order to have some |
| | | * synchronization code running during the operation process |
| | | * as pre-op, conflictRsolution, and post-op. |
| | | */ |
| | | public class MultimasterSynchronization extends SynchronizationProvider |
| | | implements ConfigAddListener, ConfigDeleteListener, ConfigChangeListener |
| | | { |
| | | static String CHANGELOG_DN = "cn=Changelog Server, cn=config"; |
| | | static String CHANGELOG_SERVER_ATTR = "ds-cfg-changelog-server"; |
| | | static String SERVER_ID_ATTR = "ds-cfg-server-id"; |
| | | static String CHANGELOG_PORT_ATTR = "ds-cfg-changelog-port"; |
| | | static String CHANGELOG_DN = "cn=Changelog Server," + |
| | | "cn=Multimaster Synchronization, cn=Synchronization Providers, cn=config"; |
| | | static String SYNCHRONIZATION_CLASS = |
| | | "ds-cfg-synchronization-provider-config"; |
| | | |
| | | private Changelog changelog = null; |
| | | private static Map<DN, SynchronizationDomain> domains = |
| | |
| | | */ |
| | | for (ConfigEntry domainEntry : configEntry.getChildren().values()) |
| | | { |
| | | if (domainEntry.hasObjectClass(SYNCHRONIZATION_CLASS)) |
| | | { |
| | | SynchronizationDomain domain = new SynchronizationDomain(domainEntry); |
| | | domains.put(domain.getBaseDN(), domain); |
| | | domain.start(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether the configuration entry that will result from a proposed |
| | |
| | | MessageHandler.registerMessage(MSGID_NEED_CHANGELOG_SERVER, |
| | | "At least one changelog server must be declared"); |
| | | MessageHandler.registerMessage(MSGID_NEED_SERVER_ID, |
| | | "The Server id must be defined"); |
| | | "The Server Id must be defined"); |
| | | MessageHandler.registerMessage(MSGID_INVALID_CHANGELOG_SERVER, |
| | | "Invalid changelog server configuration"); |
| | | MessageHandler.registerMessage(MSGID_UNKNOWN_HOSTNAME, |
| | |
| | | import org.opends.server.types.SynchronizationProviderResult; |
| | | |
| | | /** |
| | | * This class implements the multi-master functionality. |
| | | * - use the preOperation phase to add information necessary for the |
| | | * synchronization to the entry in the database (unique identifier, |
| | | * historical information, change number) |
| | | * TODO : implementation not started yet |
| | | * - use the postOperation plugin phase to forward the changes |
| | | * to the centralized changelog of the synchronization |
| | | * |
| | | * STATUS : This is a work in progress feature |
| | | * This class implements the bulk part of the.of the Directory Server side |
| | | * of the synchronization code. |
| | | * It contains the root method for publishing a change, |
| | | * processing a change received from the changelog service, |
| | | * handle conflict resolution, |
| | | * handle protocol messages from the changelog server. |
| | | */ |
| | | public class SynchronizationDomain extends DirectoryThread |
| | | implements ConfigurableComponent |
| | |
| | | |
| | | private DN configDn; |
| | | |
| | | static String CHANGELOG_DN = "cn=Changelog Server, cn=config"; |
| | | static String CHANGELOG_SERVER_ATTR = "ds-cfg-changelog-server"; |
| | | static String BASE_DN_ATTR = "ds-cfg-synchronization-dn"; |
| | | static String SERVER_ID_ATTR = "ds-cfg-server-id"; |
| | | static String CHANGELOG_PORT_ATTR = "ds-cfg-changelog-port"; |
| | | static String SERVER_ID_ATTR = "ds-cfg-directory-server-id"; |
| | | static String RECEIVE_STATUS = "ds-cfg-receive-status"; |
| | | static String MAX_RECEIVE_QUEUE = "ds-cfg-max-receive-queue"; |
| | | static String MAX_RECEIVE_DELAY = "ds-cfg-max-receive-delay"; |
| | |
| | | import org.opends.server.types.AttributeValue; |
| | | |
| | | /** |
| | | * Object used to store historical information about specific values |
| | | * Allows to store historical information about specific values |
| | | * for a given attribute. |
| | | */ |
| | | public class ValueInfo |
| New file |
| | |
| | | /* |
| | | * CDDL HEADER START |
| | | * |
| | | * The contents of this file are subject to the terms of the |
| | | * Common Development and Distribution License, Version 1.0 only |
| | | * (the "License"). You may not use this file except in compliance |
| | | * with the License. |
| | | * |
| | | * You can obtain a copy of the license at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE |
| | | * or https://OpenDS.dev.java.net/OpenDS.LICENSE. |
| | | * See the License for the specific language governing permissions |
| | | * and limitations under the License. |
| | | * |
| | | * When distributing Covered Code, include this CDDL HEADER in each |
| | | * file and include the License file at |
| | | * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, |
| | | * add the following below this CDDL HEADER, with the fields enclosed |
| | | * by brackets "[]" replaced with your own identifying * information: |
| | | * Portions Copyright [yyyy] [name of copyright owner] |
| | | * |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Portions Copyright 2006 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | /** |
| | | * This package contains the part of the Multimaster |
| | | * synchronization code that works on the Directory Server side. |
| | | * <br> |
| | | * The main classes of this core are : |
| | | * <ul> |
| | | * <li> |
| | | * <A HREF="MultimasterSynchronization.html"><B>MultimasterSynchronization |
| | | * </B></A>contains the synchronization provider |
| | | * code and more generally all the code that makes the glue between the core |
| | | * server and the synchronization code. |
| | | * </li> |
| | | * <li> |
| | | * <A HREF="SynchronizationDomain.html"><B>SynchronizationDomain</B></A> |
| | | * contains the bulk of the Directory Server side of the |
| | | * synchronization code. Most notably it contains the root method for |
| | | * publishing a change, processing a change received from the changelog |
| | | * service, handle conflict resolution, handle protocol messages from the |
| | | * changelog server. |
| | | * </li> |
| | | * <li> |
| | | * <A HREF="ChangeNumber.html"><B>ChangeNumber</B></A> |
| | | * and <A HREF="ChangeNumberGenerator.html"><B>ChangeNumberGenerator</B></A> |
| | | * contain the code related to Change Numbers code and their generation. |
| | | * </li> |
| | | * <li> |
| | | * <A HREF="ServerState.html"><B>ServerState</B></A> |
| | | * contain the code necessary for maintaining the updatedness |
| | | * of a server. |
| | | * Historical.java and the classes that it uses contain the code for |
| | | * generating and loading the historical information (only modify aspects are |
| | | * implemented) |
| | | * </li> |
| | | * <li> |
| | | * <A HREF="SynchronizationMessage.html"><B>SynchronizationMessage</B></A> |
| | | * and the classes that inherit from it contain the |
| | | * description of the protocol messages that are exchanged between the |
| | | * directory servers and the changelog servers and their encoding/decoding. |
| | | * </li> |
| | | * </ul> |
| | | */ |
| | | package org.opends.server.synchronization; |