Entry attributes for ECL - Protocol V4
| | |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 |
| | | SINGLE-VALUE |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.26027.1.1.601 |
| | | NAME 'ds-cfg-ecl-include' |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.1 |
| | | NAME 'ds-cfg-access-control-handler' |
| | | SUP top |
| | |
| | | ds-cfg-fractional-exclude $ |
| | | ds-cfg-fractional-include $ |
| | | ds-cfg-solve-conflicts $ |
| | | ds-cfg-changetime-heartbeat-interval) |
| | | ds-cfg-changetime-heartbeat-interval $ |
| | | ds-cfg-ecl-include ) |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.58 |
| | | NAME 'ds-cfg-length-based-password-validator' |
| | |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | <adm:property name="ecl-include" multi-valued="true" mandatory="false"> |
| | | <adm:synopsis> |
| | | Allows to include some target entry attributes in the ECL. |
| | | </adm:synopsis> |
| | | <adm:description> |
| | | Specifies an attribute that will be included in every External Change Log |
| | | entry related to this replication domain. |
| | | </adm:description> |
| | | <adm:default-behavior> |
| | | <adm:undefined/> |
| | | </adm:default-behavior> |
| | | <adm:syntax> |
| | | <adm:string> |
| | | <adm:pattern> |
| | | <!-- This java regex is mostly derived from keystring BNF definition |
| | | that can be found in RFC 2252, section "4.1. Common Encoding Aspects". |
| | | This can be read as: (oid|\*):oid(,oid)*+ |
| | | --> |
| | | <adm:regex>^((([a-zA-Z]([a-zA-Z]|[0-9]|-|;)*+)|(0|([1-9]([0-9])*+))(\\.(0|([1-9]([0-9])*+)))*+)|\\*):(([a-zA-Z]([a-zA-Z]|[0-9]|-|;)*+)|(0|([1-9]([0-9])*+))(\\.(0|([1-9]([0-9])*+)))*+)(,(([a-zA-Z]([a-zA-Z]|[0-9]|-|;)*+)|(0|([1-9]([0-9])*+))(\\.(0|([1-9]([0-9])*+)))*+))*+$</adm:regex> |
| | | <adm:usage>Syntax: |
| | | className:attributeName[,attributeName] |
| | | or |
| | | *:attributeName[,attributeName]. |
| | | Note that any class (className) or attribute (attributeName) definition can be replaced with its OID definition. |
| | | Examples: |
| | | inetOrgPerson:photo,jpegPhoto : 'photo' and 'jpegPhoto' attributes of any entry of type 'inetOrgPerson' class. |
| | | This can also be 2.16.840.1.113730.3.2.2:0.9.2342.19200300.100.1.7,0.9.2342.19200300.100.1.60 or a mix. |
| | | *:jpegPhoto : the 'jpegPhoto' attribute of any entry that has this attribute. |
| | | This can also be *:0.9.2342.19200300.100.1.60 |
| | | </adm:usage> |
| | | <adm:synopsis> |
| | | Defines attribute(s) of one particular class or of all possible |
| | | classes, to exclude from the replication. |
| | | </adm:synopsis> |
| | | </adm:pattern> |
| | | </adm:string> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:name>ds-cfg-ecl-include</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | </adm:managed-object> |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.replication.common; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | /** |
| | | * This class holds information about a DS connected to the topology. This |
| | |
| | | // Group id |
| | | private byte groupId = (byte) -1; |
| | | |
| | | private Set<String> eclIncludes = new HashSet<String>(); |
| | | |
| | | /** |
| | | * Creates a new instance of DSInfo with every given info. |
| | | * |
| | |
| | | * @param safeDataLevel DS safe data level |
| | | * @param groupId DS group id |
| | | * @param refUrls DS exported referrals URLs |
| | | * @param eclIncludes The list of entry attributes to include in the ECL. |
| | | */ |
| | | public DSInfo(short dsId, short rsId, long generationId, ServerStatus status, |
| | | boolean assuredFlag, AssuredMode assuredMode, byte safeDataLevel, |
| | | byte groupId, List<String> refUrls) |
| | | byte groupId, List<String> refUrls, Set<String> eclIncludes) |
| | | { |
| | | |
| | | this.dsId = dsId; |
| | |
| | | this.safeDataLevel = safeDataLevel; |
| | | this.groupId = groupId; |
| | | this.refUrls = refUrls; |
| | | this.eclIncludes = eclIncludes; |
| | | } |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * Get the entry attributes to be included in the ECL. |
| | | * @return a. |
| | | */ |
| | | public Set<String> getEclIncludes() |
| | | { |
| | | return eclIncludes; |
| | | } |
| | | |
| | | /** |
| | | * Test if the passed object is equal to this one. |
| | | * @param obj The object to test |
| | | * @return True if both objects are equal |
| | |
| | | (assuredMode == dsInfo.getAssuredMode()) && |
| | | (safeDataLevel == dsInfo.getSafeDataLevel()) && |
| | | (groupId == dsInfo.getGroupId()) && |
| | | (refUrls.equals(dsInfo.getRefUrls()))); |
| | | (refUrls.equals(dsInfo.getRefUrls())) && |
| | | (eclIncludes.equals(dsInfo.getEclIncludes()))); |
| | | } else |
| | | { |
| | | return false; |
| | |
| | | 73 * hash + (this.assuredMode != null ? this.assuredMode.hashCode() : 0); |
| | | hash = 73 * hash + this.safeDataLevel; |
| | | hash = 73 * hash + (this.refUrls != null ? this.refUrls.hashCode() : 0); |
| | | hash = 73 * hash + (this.eclIncludes != null ? eclIncludes.hashCode() : 0); |
| | | hash = 73 * hash + this.groupId; |
| | | return hash; |
| | | } |
| | |
| | | sb.append(groupId); |
| | | sb.append("\nReferral URLs: "); |
| | | sb.append(refUrls); |
| | | sb.append("\nECL Include: "); |
| | | sb.append(eclIncludes); |
| | | return sb.toString(); |
| | | } |
| | | |
| | |
| | | import static org.opends.server.util.StaticUtils.getFileForPath; |
| | | import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString; |
| | | |
| | | import org.opends.server.replication.protocol.LDAPUpdateMsg; |
| | | |
| | | import org.opends.server.replication.service.ReplicationMonitor; |
| | | |
| | | import java.util.Collection; |
| | | |
| | | import org.opends.server.types.Attributes; |
| | | |
| | | import java.io.File; |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.util.ArrayList; |
| | | import java.util.Collection; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.Iterator; |
| | |
| | | import org.opends.server.protocols.ldap.LDAPAttribute; |
| | | import org.opends.server.protocols.ldap.LDAPFilter; |
| | | import org.opends.server.protocols.ldap.LDAPModification; |
| | | import org.opends.server.replication.service.ReplicationDomain; |
| | | import org.opends.server.replication.common.AssuredMode; |
| | | import org.opends.server.replication.common.ChangeNumber; |
| | | import org.opends.server.replication.common.ChangeNumberGenerator; |
| | |
| | | import org.opends.server.replication.protocol.AddContext; |
| | | import org.opends.server.replication.protocol.AddMsg; |
| | | import org.opends.server.replication.protocol.DeleteContext; |
| | | import org.opends.server.replication.protocol.DeleteMsg; |
| | | import org.opends.server.replication.protocol.LDAPUpdateMsg; |
| | | import org.opends.server.replication.protocol.ModifyContext; |
| | | import org.opends.server.replication.protocol.ModifyDNMsg; |
| | | import org.opends.server.replication.protocol.ModifyDnContext; |
| | |
| | | import org.opends.server.replication.protocol.ProtocolSession; |
| | | import org.opends.server.replication.protocol.RoutableMsg; |
| | | import org.opends.server.replication.protocol.UpdateMsg; |
| | | import org.opends.server.replication.service.ReplicationDomain; |
| | | import org.opends.server.replication.service.ReplicationMonitor; |
| | | import org.opends.server.tasks.TaskUtils; |
| | | import org.opends.server.types.AbstractOperation; |
| | | import org.opends.server.types.Attribute; |
| | |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.AttributeValues; |
| | | import org.opends.server.types.Attributes; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ConfigChangeResult; |
| | | import org.opends.server.types.Control; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DebugLogLevel; |
| | | import org.opends.server.types.DereferencePolicy; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.opends.server.types.Entry; |
| | |
| | | import org.opends.server.types.SearchScope; |
| | | import org.opends.server.types.SynchronizationProviderResult; |
| | | import org.opends.server.types.operation.PluginOperation; |
| | | import org.opends.server.types.operation.PostOperationAddOperation; |
| | | import org.opends.server.types.operation.PostOperationDeleteOperation; |
| | | import org.opends.server.types.operation.PostOperationModifyDNOperation; |
| | | import org.opends.server.types.operation.PostOperationModifyOperation; |
| | | import org.opends.server.types.operation.PostOperationOperation; |
| | | import org.opends.server.types.operation.PreOperationAddOperation; |
| | | import org.opends.server.types.operation.PreOperationDeleteOperation; |
| | |
| | | // The operation should become a no-op |
| | | private static final int FRACTIONAL_BECOME_NO_OP = 3; |
| | | |
| | | |
| | | /** |
| | | * The thread that periodically saves the ServerState of this |
| | | * LDAPReplicationDomain in the database. |
| | |
| | | setGroupId((byte)configuration.getGroupId()); |
| | | setURLs(configuration.getReferralsUrl()); |
| | | |
| | | setCfgEclInclude(configuration.getEclInclude()); |
| | | |
| | | /* |
| | | * Modify conflicts are solved for all suffixes but the schema suffix |
| | | * because we don't want to store extra information in the schema |
| | |
| | | } |
| | | else |
| | | { |
| | | try |
| | | { |
| | | addEntryAttributesForCL(msg,op); |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | TRACER.debugCaught(DebugLogLevel.ERROR, e); |
| | | } |
| | | // If assured replication is configured, this will prepare blocking |
| | | // mechanism. If assured replication is disabled, this returns |
| | | // immediately |
| | |
| | | } |
| | | |
| | | /** |
| | | * Called by synchronize post op plugin in order to add the entry historized |
| | | * attributes to the UpdateMsg. |
| | | * @param msg |
| | | * @param op |
| | | * @throws DirectoryException |
| | | */ |
| | | private void addEntryAttributesForCL(UpdateMsg msg,PostOperationOperation op) |
| | | throws DirectoryException |
| | | { |
| | | String[] entryAttributeNames = |
| | | getEclInclude().toArray(new String[0]); |
| | | ArrayList<Attribute> newattrs = new ArrayList<Attribute>(); |
| | | |
| | | if (op instanceof PostOperationDeleteOperation) |
| | | { |
| | | Entry entry = null; |
| | | PostOperationDeleteOperation delOp = (PostOperationDeleteOperation)op; |
| | | entry = delOp.getEntryToDelete(); |
| | | for (String name : entryAttributeNames) |
| | | { |
| | | AttributeType atype = DirectoryServer.getAttributeType(name); |
| | | List<Attribute> attrs = entry.getAttribute(atype); |
| | | for (Attribute a : attrs) |
| | | newattrs.add(a); |
| | | } |
| | | ((DeleteMsg)msg).setEclIncludes(newattrs); |
| | | } |
| | | else if (op instanceof PostOperationModifyOperation) |
| | | { |
| | | Entry entry = null; |
| | | PostOperationModifyOperation modOp = (PostOperationModifyOperation)op; |
| | | entry = modOp.getCurrentEntry(); |
| | | for (String name : entryAttributeNames) |
| | | { |
| | | AttributeType atype = DirectoryServer.getAttributeType(name); |
| | | List<Attribute> attrs = entry.getAttribute(atype); |
| | | for (Attribute a : attrs) |
| | | newattrs.add(a); |
| | | } |
| | | ((ModifyMsg)msg).setEclIncludes(newattrs); |
| | | } |
| | | else if (op instanceof PostOperationModifyDNOperation) |
| | | { |
| | | Entry entry = null; |
| | | PostOperationModifyDNOperation modDNOp = |
| | | (PostOperationModifyDNOperation)op; |
| | | entry = modDNOp.getOriginalEntry(); |
| | | for (String name : entryAttributeNames) |
| | | { |
| | | AttributeType atype = DirectoryServer.getAttributeType(name); |
| | | List<Attribute> attrs = entry.getAttribute(atype); |
| | | for (Attribute a : attrs) |
| | | newattrs.add(a); |
| | | } |
| | | ((ModifyDNMsg)msg).setEclIncludes(newattrs); |
| | | } |
| | | else if (op instanceof PostOperationAddOperation) |
| | | { |
| | | Entry entry = null; |
| | | PostOperationAddOperation addOp = (PostOperationAddOperation)op; |
| | | entry = addOp.getEntryToAdd(); |
| | | for (String name : entryAttributeNames) |
| | | { |
| | | AttributeType atype = DirectoryServer.getAttributeType(name); |
| | | List<Attribute> attrs = entry.getAttribute(atype); |
| | | if (attrs != null) |
| | | { |
| | | for (Attribute a : attrs) |
| | | newattrs.add(a); |
| | | } |
| | | else |
| | | { |
| | | // FIXME:ECL |
| | | } |
| | | } |
| | | ((AddMsg)msg).setEclIncludes(newattrs); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Gets the fractional configuration of this domain. |
| | | * @return The fractional configuration of this domain. |
| | | */ |
| | |
| | | import org.opends.server.protocols.asn1.ASN1Writer; |
| | | import org.opends.server.protocols.asn1.ASN1; |
| | | import org.opends.server.protocols.asn1.ASN1Exception; |
| | | import org.opends.server.protocols.asn1.ASN1Reader; |
| | | import org.opends.server.replication.common.ChangeNumber; |
| | | import org.opends.server.types.*; |
| | | import org.opends.server.types.operation.PostOperationAddOperation; |
| | |
| | | */ |
| | | public class AddMsg extends LDAPUpdateMsg |
| | | { |
| | | // Attributes are managed encoded |
| | | private byte[] encodedAttributes; |
| | | |
| | | // Parent is managed decoded |
| | | private String parentUniqueId; |
| | | |
| | | /** |
| | |
| | | op.getRawEntryDN().toString()); |
| | | |
| | | AddContext ctx = (AddContext) op.getAttachment(SYNCHROCONTEXT); |
| | | |
| | | // Stores parentUniqueID not encoded |
| | | this.parentUniqueId = ctx.getParentUid(); |
| | | |
| | | this.encodedAttributes = |
| | | encodeAttributes(op.getObjectClasses(), |
| | | op.getUserAttributes(), |
| | | op.getOperationalAttributes()); |
| | | // Stores attributes encoded |
| | | this.encodedAttributes = encodeAttributes(op.getObjectClasses(), |
| | | op.getUserAttributes(), op.getOperationalAttributes()); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new AddMessage. |
| | | * |
| | | * @param cn ChangeNumber of the add. |
| | | * @param dn DN of the added entry. |
| | | * @param uniqueId The Unique identifier of the added entry. |
| | | * @param parentId The unique Id of the parent of the added |
| | | * entry. |
| | | * @param objectClasses objectclass of the added entry. |
| | | * @param userAttributes user attributes of the added entry. |
| | | * @param operationalAttributes operational attributes of the added entry. |
| | | */ |
| | | public AddMsg(ChangeNumber cn, |
| | | String dn, |
| | | String uniqueId, |
| | | String parentId, |
| | | Map<ObjectClass, String> objectClasses, |
| | | Map<AttributeType,List<Attribute>> userAttributes, |
| | | Map<AttributeType,List<Attribute>> operationalAttributes) |
| | | { |
| | | super (cn, uniqueId, dn); |
| | | |
| | | // Stores parentUniqueID not encoded |
| | | this.parentUniqueId = parentId; |
| | | |
| | | // Stores attributes encoded |
| | | this.encodedAttributes = encodeAttributes(objectClasses, userAttributes, |
| | | operationalAttributes); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Creates a new AddMessage. |
| | | * |
| | | * @param cn ChangeNumber of the add. |
| | | * @param dn DN of the added entry. |
| | | * @param uniqueId The Unique identifier of the added entry. |
| | | * @param parentId The unique Id of the parent of the added entry. |
| | | * @param objectClass objectclass of the added entry. |
| | | * @param userAttributes user attributes of the added entry. |
| | | * @param operationalAttributes operational attributes of the added entry. |
| | | */ |
| | | public AddMsg(ChangeNumber cn, |
| | | String dn, |
| | | String uniqueId, |
| | | String parentId, |
| | | Attribute objectClass, |
| | | Collection<Attribute> userAttributes, |
| | | Collection<Attribute> operationalAttributes) |
| | | { |
| | | super (cn, uniqueId, dn); |
| | | |
| | | // Stores parentUniqueID not encoded |
| | | this.parentUniqueId = parentId; |
| | | |
| | | // Stores attributes encoded |
| | | this.encodedAttributes = encodeAttributes(objectClass, userAttributes, |
| | | operationalAttributes); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new Add message from a byte[]. |
| | | * |
| | | * @param in The byte[] from which the operation must be read. |
| | | * @throws DataFormatException The input byte[] is not a valid AddMsg |
| | | * @throws UnsupportedEncodingException If UTF8 is not supported by the jvm |
| | | */ |
| | | public AddMsg(byte[] in) throws DataFormatException, |
| | | UnsupportedEncodingException |
| | | { |
| | | byte[] allowedPduTypes = new byte[2]; |
| | | allowedPduTypes[0] = MSG_TYPE_ADD; |
| | | allowedPduTypes[1] = MSG_TYPE_ADD_V1; |
| | | int pos = decodeHeader(allowedPduTypes, in); |
| | | |
| | | // protocol version has been read as part of the header |
| | | if (protocolVersion <= 3) |
| | | decodeBody_V123(in, pos); |
| | | else |
| | | { |
| | | decodeBody_V4(in, pos); |
| | | } |
| | | if (protocolVersion==ProtocolVersion.getCurrentVersion()) |
| | | { |
| | | bytes = in; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public AddOperationBasis createOperation( |
| | | InternalClientConnection connection, String newDn) |
| | | throws LDAPException, ASN1Exception |
| | | { |
| | | ArrayList<RawAttribute> attr = decodeRawAttributes(encodedAttributes); |
| | | |
| | | AddOperationBasis add = new AddOperationBasis(connection, |
| | | InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), null, |
| | | ByteString.valueOf(newDn), attr); |
| | | AddContext ctx = new AddContext(getChangeNumber(), getUniqueId(), |
| | | parentUniqueId); |
| | | add.setAttachment(SYNCHROCONTEXT, ctx); |
| | | return add; |
| | | } |
| | | |
| | | // ============ |
| | | // Msg encoding |
| | | // ============ |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes_V1() throws UnsupportedEncodingException |
| | | { |
| | | int bodyLength = encodedAttributes.length; |
| | | byte[] byteParentId = null; |
| | | if (parentUniqueId != null) |
| | | { |
| | | byteParentId = parentUniqueId.getBytes("UTF-8"); |
| | | bodyLength += byteParentId.length + 1; |
| | | } |
| | | else |
| | | { |
| | | bodyLength += 1; |
| | | } |
| | | |
| | | /* encode the header in a byte[] large enough to also contain the mods */ |
| | | byte [] resultByteArray = encodeHeader_V1(MSG_TYPE_ADD_V1, bodyLength); |
| | | |
| | | int pos = resultByteArray.length - bodyLength; |
| | | |
| | | if (byteParentId != null) |
| | | pos = addByteArray(byteParentId, resultByteArray, pos); |
| | | else |
| | | resultByteArray[pos++] = 0; |
| | | |
| | | /* put the attributes */ |
| | | for (int i=0; i<encodedAttributes.length; i++,pos++) |
| | | { |
| | | resultByteArray[pos] = encodedAttributes[i]; |
| | | } |
| | | return resultByteArray; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes_V23() throws UnsupportedEncodingException |
| | | { |
| | | // Put together the different encoded pieces |
| | | int bodyLength = encodedAttributes.length; |
| | | |
| | | // Compute the total length of the body |
| | | byte[] byteParentId = null; |
| | | if (parentUniqueId != null) |
| | | { |
| | | // Encode parentID now to get the length of the encoded bytes |
| | | byteParentId = parentUniqueId.getBytes("UTF-8"); |
| | | bodyLength += byteParentId.length + 1; |
| | | } |
| | | else |
| | | { |
| | | bodyLength += 1; |
| | | } |
| | | |
| | | /* encode the header in a byte[] large enough to also contain the mods */ |
| | | byte [] resultByteArray = encodeHeader(MSG_TYPE_ADD, bodyLength); |
| | | |
| | | int pos = resultByteArray.length - bodyLength; |
| | | |
| | | if (byteParentId != null) |
| | | pos = addByteArray(byteParentId, resultByteArray, pos); |
| | | else |
| | | resultByteArray[pos++] = 0; |
| | | |
| | | /* put the attributes */ |
| | | for (int i=0; i<encodedAttributes.length; i++,pos++) |
| | | { |
| | | resultByteArray[pos] = encodedAttributes[i]; |
| | | } |
| | | return resultByteArray; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes_V4() throws UnsupportedEncodingException |
| | | { |
| | | // Put together the different encoded pieces |
| | | int bodyLength = 0; |
| | | |
| | | // Compute the total length of the body |
| | | byte[] byteParentId = null; |
| | | if (parentUniqueId != null) |
| | | { |
| | | // Encode parentID now to get the length of the encoded bytes |
| | | byteParentId = parentUniqueId.getBytes("UTF-8"); |
| | | bodyLength += byteParentId.length + 1; |
| | | } |
| | | else |
| | | { |
| | | bodyLength += 1; |
| | | } |
| | | |
| | | byte[] byteAttrLen = |
| | | String.valueOf(encodedAttributes.length).getBytes("UTF-8"); |
| | | bodyLength += byteAttrLen.length + 1; |
| | | bodyLength += encodedAttributes.length + 1; |
| | | |
| | | byte[] byteEntryAttrLen = |
| | | String.valueOf(encodedEclIncludes.length).getBytes("UTF-8"); |
| | | bodyLength += byteEntryAttrLen.length + 1; |
| | | bodyLength += encodedEclIncludes.length + 1; |
| | | |
| | | /* encode the header in a byte[] large enough to also contain the mods */ |
| | | byte [] encodedMsg = encodeHeader(MSG_TYPE_ADD, bodyLength); |
| | | |
| | | int pos = encodedMsg.length - bodyLength; |
| | | if (byteParentId != null) |
| | | pos = addByteArray(byteParentId, encodedMsg, pos); |
| | | else |
| | | encodedMsg[pos++] = 0; |
| | | pos = addByteArray(byteAttrLen, encodedMsg, pos); |
| | | pos = addByteArray(encodedAttributes, encodedMsg, pos); |
| | | pos = addByteArray(byteEntryAttrLen, encodedMsg, pos); |
| | | pos = addByteArray(encodedEclIncludes, encodedMsg, pos); |
| | | return encodedMsg; |
| | | } |
| | | |
| | | private byte[] encodeAttributes( |
| | |
| | | return byteBuilder.toByteArray(); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new AddMessage. |
| | | * |
| | | * @param cn ChangeNumber of the add. |
| | | * @param dn DN of the added entry. |
| | | * @param uniqueId The Unique identifier of the added entry. |
| | | * @param parentId The unique Id of the parent of the added |
| | | * entry. |
| | | * @param objectClasses objectclass of the added entry. |
| | | * @param userAttributes user attributes of the added entry. |
| | | * @param operationalAttributes operational attributes of the added entry. |
| | | */ |
| | | public AddMsg(ChangeNumber cn, |
| | | String dn, |
| | | String uniqueId, |
| | | String parentId, |
| | | Map<ObjectClass, String> objectClasses, |
| | | Map<AttributeType,List<Attribute>> userAttributes, |
| | | Map<AttributeType,List<Attribute>> operationalAttributes) |
| | | private byte[] encodeAttributes( |
| | | Attribute objectClass, |
| | | Collection<Attribute> userAttributes, |
| | | Collection<Attribute> operationalAttributes) |
| | | { |
| | | super (cn, uniqueId, dn); |
| | | this.parentUniqueId = parentId; |
| | | |
| | | encodedAttributes = encodeAttributes(objectClasses, |
| | | userAttributes, operationalAttributes); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Creates a new AddMessage. |
| | | * |
| | | * @param cn ChangeNumber of the add. |
| | | * @param dn DN of the added entry. |
| | | * @param uniqueId The Unique identifier of the added entry. |
| | | * @param parentId The unique Id of the parent of the added entry. |
| | | * @param objectClass objectclass of the added entry. |
| | | * @param userAttributes user attributes of the added entry. |
| | | * @param operationalAttributes operational attributes of the added entry. |
| | | */ |
| | | public AddMsg(ChangeNumber cn, |
| | | String dn, |
| | | String uniqueId, |
| | | String parentId, |
| | | Attribute objectClass, |
| | | Collection<Attribute> userAttributes, |
| | | Collection<Attribute> operationalAttributes) |
| | | { |
| | | super (cn, uniqueId, dn); |
| | | this.parentUniqueId = parentId; |
| | | |
| | | ByteStringBuilder byteBuilder = new ByteStringBuilder(); |
| | | ASN1Writer writer = ASN1.getWriter(byteBuilder); |
| | | |
| | | try |
| | | { |
| | | new LDAPAttribute(objectClass).write(writer); |
| | |
| | | { |
| | | // Do something |
| | | } |
| | | |
| | | encodedAttributes = byteBuilder.toByteArray(); |
| | | return byteBuilder.toByteArray(); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new Add message from a byte[]. |
| | | * |
| | | * @param in The byte[] from which the operation must be read. |
| | | * @throws DataFormatException The input byte[] is not a valid AddMsg |
| | | * @throws UnsupportedEncodingException If UTF8 is not supported by the jvm |
| | | */ |
| | | public AddMsg(byte[] in) throws DataFormatException, |
| | | UnsupportedEncodingException |
| | | { |
| | | byte[] allowedPduTypes = new byte[2]; |
| | | allowedPduTypes[0] = MSG_TYPE_ADD; |
| | | allowedPduTypes[1] = MSG_TYPE_ADD_V1; |
| | | int pos = decodeHeader(allowedPduTypes, in); |
| | | // ============ |
| | | // Msg decoding |
| | | // ============ |
| | | |
| | | private void decodeBody_V123(byte[] in, int pos) |
| | | throws DataFormatException, UnsupportedEncodingException |
| | | { |
| | | // read the parent unique Id |
| | | int length = getNextLength(in, pos); |
| | | if (length != 0) |
| | |
| | | pos += 1; |
| | | } |
| | | |
| | | // Read the attributes : all the remaining bytes |
| | | // Read/Don't decode attributes : all the remaining bytes |
| | | encodedAttributes = new byte[in.length-pos]; |
| | | int i =0; |
| | | while (pos<in.length) |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public AddOperationBasis createOperation( |
| | | InternalClientConnection connection, String newDn) |
| | | throws LDAPException, ASN1Exception |
| | | private void decodeBody_V4(byte[] in, int pos) |
| | | throws DataFormatException, UnsupportedEncodingException |
| | | { |
| | | ASN1Reader asn1Reader = ASN1.getReader(encodedAttributes); |
| | | ArrayList<RawAttribute> attr = new ArrayList<RawAttribute>(); |
| | | |
| | | while(asn1Reader.hasNextElement()) |
| | | // read the parent unique Id |
| | | int length = getNextLength(in, pos); |
| | | if (length != 0) |
| | | { |
| | | attr.add(LDAPAttribute.decode(asn1Reader)); |
| | | } |
| | | |
| | | AddOperationBasis add = new AddOperationBasis(connection, |
| | | InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), null, |
| | | ByteString.valueOf(newDn), attr); |
| | | AddContext ctx = new AddContext(getChangeNumber(), getUniqueId(), |
| | | parentUniqueId); |
| | | add.setAttachment(SYNCHROCONTEXT, ctx); |
| | | return add; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes() throws UnsupportedEncodingException |
| | | { |
| | | if (bytes == null) |
| | | { |
| | | int length = encodedAttributes.length; |
| | | byte[] byteParentId = null; |
| | | if (parentUniqueId != null) |
| | | { |
| | | byteParentId = parentUniqueId.getBytes("UTF-8"); |
| | | length += byteParentId.length + 1; |
| | | } |
| | | else |
| | | { |
| | | length += 1; |
| | | } |
| | | |
| | | /* encode the header in a byte[] large enough to also contain the mods */ |
| | | byte [] resultByteArray = encodeHeader(MSG_TYPE_ADD, length); |
| | | |
| | | int pos = resultByteArray.length - length; |
| | | |
| | | if (byteParentId != null) |
| | | pos = addByteArray(byteParentId, resultByteArray, pos); |
| | | else |
| | | resultByteArray[pos++] = 0; |
| | | |
| | | /* put the attributes */ |
| | | for (int i=0; i<encodedAttributes.length; i++,pos++) |
| | | { |
| | | resultByteArray[pos] = encodedAttributes[i]; |
| | | } |
| | | return resultByteArray; |
| | | parentUniqueId = new String(in, pos, length, "UTF-8"); |
| | | pos += length + 1; |
| | | } |
| | | else |
| | | { |
| | | return bytes; |
| | | parentUniqueId = null; |
| | | pos += 1; |
| | | } |
| | | |
| | | // Read attr len |
| | | length = getNextLength(in, pos); |
| | | int attrLen = Integer.valueOf(new String(in, pos, length,"UTF-8")); |
| | | pos += length + 1; |
| | | |
| | | // Read/Don't decode attributes |
| | | this.encodedAttributes = new byte[attrLen]; |
| | | try |
| | | { |
| | | System.arraycopy(in, pos, encodedAttributes, 0, attrLen); |
| | | } catch (IndexOutOfBoundsException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (ArrayStoreException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (NullPointerException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | pos += attrLen + 1; |
| | | |
| | | // Read ecl attr len |
| | | length = getNextLength(in, pos); |
| | | int eclAttrLen = Integer.valueOf(new String(in, pos, length,"UTF-8")); |
| | | pos += length + 1; |
| | | |
| | | // Read/Don't decode entry attributes |
| | | encodedEclIncludes = new byte[eclAttrLen]; |
| | | try |
| | | { |
| | | System.arraycopy(in, pos, encodedEclIncludes, 0, eclAttrLen); |
| | | } catch (IndexOutOfBoundsException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (ArrayStoreException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (NullPointerException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | |
| | | */ |
| | | public List<Attribute> getAttributes() throws LDAPException, ASN1Exception |
| | | { |
| | | List<Attribute> attrs = new ArrayList<Attribute>(); |
| | | |
| | | ASN1Reader reader = ASN1.getReader(encodedAttributes); |
| | | |
| | | while (reader.hasNextElement()) |
| | | attrs.add(LDAPAttribute.decode(reader).toAttribute()); |
| | | |
| | | List<Attribute> attrs = decodeAttributes(encodedAttributes); |
| | | return attrs; |
| | | } |
| | | |
| | |
| | | @Override |
| | | public int size() |
| | | { |
| | | return encodedAttributes.length + 40; |
| | | return encodedAttributes.length + + encodedEclIncludes.length |
| | | + headerSize(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes_V1() throws UnsupportedEncodingException |
| | | { |
| | | int length = encodedAttributes.length; |
| | | byte[] byteParentId = null; |
| | | if (parentUniqueId != null) |
| | | { |
| | | byteParentId = parentUniqueId.getBytes("UTF-8"); |
| | | length += byteParentId.length + 1; |
| | | } |
| | | else |
| | | { |
| | | length += 1; |
| | | } |
| | | |
| | | /* encode the header in a byte[] large enough to also contain the mods */ |
| | | byte [] resultByteArray = encodeHeader_V1(MSG_TYPE_ADD_V1, length); |
| | | |
| | | int pos = resultByteArray.length - length; |
| | | |
| | | if (byteParentId != null) |
| | | pos = addByteArray(byteParentId, resultByteArray, pos); |
| | | else |
| | | resultByteArray[pos++] = 0; |
| | | |
| | | /* put the attributes */ |
| | | for (int i=0; i<encodedAttributes.length; i++,pos++) |
| | | { |
| | | resultByteArray[pos] = encodedAttributes[i]; |
| | | } |
| | | return resultByteArray; |
| | | } |
| | | } |
| | |
| | | byte[] allowedPduTypes = new byte[2]; |
| | | allowedPduTypes[0] = MSG_TYPE_DELETE; |
| | | allowedPduTypes[1] = MSG_TYPE_DELETE_V1; |
| | | decodeHeader(allowedPduTypes, in); |
| | | int pos = decodeHeader(allowedPduTypes, in); |
| | | |
| | | // protocol version has been read as part of the header |
| | | if (protocolVersion >= 4) |
| | | decodeBody_V4(in, pos); |
| | | } |
| | | |
| | | |
| | |
| | | InternalClientConnection connection, String newDn) |
| | | { |
| | | DeleteOperationBasis del = new DeleteOperationBasis(connection, |
| | | InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), null, |
| | | InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), null, |
| | | ByteString.valueOf(newDn)); |
| | | DeleteContext ctx = new DeleteContext(getChangeNumber(), getUniqueId()); |
| | | del.setAttachment(SYNCHROCONTEXT, ctx); |
| | | return del; |
| | | } |
| | | |
| | | // ============ |
| | | // Msg encoding |
| | | // ============ |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public byte[] getBytes_V1() throws UnsupportedEncodingException |
| | | { |
| | | return encodeHeader_V1(MSG_TYPE_DELETE_V1, 0); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes() throws UnsupportedEncodingException |
| | | public byte[] getBytes_V23() throws UnsupportedEncodingException |
| | | { |
| | | if (bytes == null) |
| | | return encodeHeader(MSG_TYPE_DELETE, 0); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes_V4() throws UnsupportedEncodingException |
| | | { |
| | | // Put together the different encoded pieces |
| | | int bodyLength = 0; |
| | | |
| | | byte[] byteEntryAttrLen = |
| | | String.valueOf(encodedEclIncludes.length).getBytes("UTF-8"); |
| | | bodyLength += byteEntryAttrLen.length + 1; |
| | | bodyLength += encodedEclIncludes.length + 1; |
| | | |
| | | /* encode the header in a byte[] large enough to also contain the mods */ |
| | | byte [] encodedMsg = encodeHeader(MSG_TYPE_DELETE, bodyLength); |
| | | int pos = encodedMsg.length - bodyLength; |
| | | pos = addByteArray(byteEntryAttrLen, encodedMsg, pos); |
| | | pos = addByteArray(encodedEclIncludes, encodedMsg, pos); |
| | | return encodedMsg; |
| | | } |
| | | |
| | | // ============ |
| | | // Msg decoding |
| | | // ============ |
| | | |
| | | private void decodeBody_V4(byte[] in, int pos) |
| | | throws DataFormatException, UnsupportedEncodingException |
| | | { |
| | | // Read ecl attr len |
| | | int length = getNextLength(in, pos); |
| | | int eclAttrLen = Integer.valueOf(new String(in, pos, length,"UTF-8")); |
| | | pos += length + 1; |
| | | |
| | | // Read/Don't decode entry attributes |
| | | encodedEclIncludes = new byte[eclAttrLen]; |
| | | try |
| | | { |
| | | return encodeHeader(MSG_TYPE_DELETE, 0); |
| | | } |
| | | else |
| | | System.arraycopy(in, pos, encodedEclIncludes, 0, eclAttrLen); |
| | | } catch (IndexOutOfBoundsException e) |
| | | { |
| | | return bytes; |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (ArrayStoreException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (NullPointerException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | |
| | | @Override |
| | | public int size() |
| | | { |
| | | // The DeleteMsg size is mostly dependent on the DN and should never |
| | | // grow very large. It is therefore safe to assume an average of 40 bytes. |
| | | return 40; |
| | | return encodedEclIncludes.length + headerSize(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public byte[] getBytes_V1() throws UnsupportedEncodingException |
| | | { |
| | | return encodeHeader_V1(MSG_TYPE_DELETE_V1, 0); |
| | | } |
| | | } |
| | |
| | | package org.opends.server.replication.protocol; |
| | | |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.zip.DataFormatException; |
| | | |
| | | import org.opends.server.protocols.asn1.ASN1; |
| | | import org.opends.server.protocols.asn1.ASN1Exception; |
| | | import org.opends.server.protocols.asn1.ASN1Reader; |
| | | import org.opends.server.protocols.asn1.ASN1Writer; |
| | | import org.opends.server.protocols.internal.InternalClientConnection; |
| | | import org.opends.server.protocols.ldap.LDAPAttribute; |
| | | import org.opends.server.replication.common.AssuredMode; |
| | | import org.opends.server.replication.common.ChangeNumber; |
| | | import org.opends.server.types.AbstractOperation; |
| | | import org.opends.server.types.Attribute; |
| | | import org.opends.server.types.ByteSequenceReader; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ByteStringBuilder; |
| | | import org.opends.server.types.LDAPException; |
| | | import org.opends.server.types.RawAttribute; |
| | | import org.opends.server.types.operation.PostOperationAddOperation; |
| | | import org.opends.server.types.operation.PostOperationDeleteOperation; |
| | | import org.opends.server.types.operation.PostOperationModifyDNOperation; |
| | |
| | | protected byte[] bytes = null; |
| | | |
| | | /** |
| | | * Encoded form of entry attributes. |
| | | */ |
| | | protected byte[] encodedEclIncludes = new byte[0]; |
| | | |
| | | /** |
| | | * Creates a new UpdateMsg. |
| | | */ |
| | | public LDAPUpdateMsg() |
| | |
| | | } |
| | | |
| | | /** |
| | | * Do all the work necessary for the encoding. |
| | | * |
| | | * This is useful in case when one wants to perform this outside |
| | | * of a synchronized portion of code. |
| | | * |
| | | * This method is not synchronized and therefore not MT safe. |
| | | * |
| | | * @throws UnsupportedEncodingException when encoding fails. |
| | | */ |
| | | public void encode() throws UnsupportedEncodingException |
| | | { |
| | | bytes = getBytes(); |
| | | } |
| | | |
| | | /** |
| | | * Create and Operation from the message. |
| | | * |
| | | * @param conn connection to use when creating the message |
| | |
| | | InternalClientConnection conn, String newDn) |
| | | throws LDAPException, ASN1Exception, DataFormatException; |
| | | |
| | | |
| | | // ============ |
| | | // Msg encoding |
| | | // ============ |
| | | |
| | | /** |
| | | * Do all the work necessary for the encoding. |
| | | * |
| | | * This is useful in case when one wants to perform this outside |
| | | * of a synchronized portion of code. |
| | | * |
| | | * This method is not synchronized and therefore not MT safe. |
| | | * |
| | | * @throws UnsupportedEncodingException when encoding fails. |
| | | */ |
| | | public void encode() throws UnsupportedEncodingException |
| | | { |
| | | bytes = getBytes(); |
| | | } |
| | | |
| | | /** |
| | | * Encode the common header for all the UpdateMsg. This uses the current |
| | | * protocol version. |
| | |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes(short reqProtocolVersion) |
| | | throws UnsupportedEncodingException |
| | | { |
| | | if (reqProtocolVersion == ProtocolVersion.REPLICATION_PROTOCOL_V1) |
| | | return getBytes_V1(); |
| | | else |
| | | return getBytes(); |
| | | } |
| | | |
| | | /** |
| | | * Get the byte array representation of this Message. This uses the version |
| | | * 1 of the replication protocol (used for compatibility purpose). |
| | | * |
| | | * @return The byte array representation of this Message. |
| | | * |
| | | * @throws UnsupportedEncodingException When the encoding of the message |
| | | * failed because the UTF-8 encoding is not supported. |
| | | */ |
| | | public abstract byte[] getBytes_V1() throws UnsupportedEncodingException; |
| | | |
| | | /** |
| | | * Encode the common header for all the UpdateMessage. This uses the version |
| | | * 1 of the replication protocol (used for compatibility purpose). |
| | | * |
| | |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes() |
| | | throws UnsupportedEncodingException |
| | | { |
| | | // Encode in the current protocol version |
| | | if (bytes == null) |
| | | { |
| | | // this is the current version of the protocol |
| | | bytes = getBytes_V4(); |
| | | } |
| | | return bytes; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes(short reqProtocolVersion) |
| | | throws UnsupportedEncodingException |
| | | { |
| | | if (reqProtocolVersion == ProtocolVersion.REPLICATION_PROTOCOL_V1) |
| | | { |
| | | return getBytes_V1(); |
| | | } |
| | | else if (reqProtocolVersion <= ProtocolVersion.REPLICATION_PROTOCOL_V3) |
| | | { |
| | | return getBytes_V23(); |
| | | } |
| | | else |
| | | { |
| | | // Encode in the current protocol version |
| | | if (bytes == null) |
| | | { |
| | | // this is the current version of the protocol |
| | | bytes = getBytes_V4(); |
| | | } |
| | | return bytes; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the byte array representation of this Message. This uses the version |
| | | * 1 of the replication protocol (used for compatibility purpose). |
| | | * |
| | | * @return The byte array representation of this Message. |
| | | * |
| | | * @throws UnsupportedEncodingException When the encoding of the message |
| | | * failed because the UTF-8 encoding is not supported. |
| | | */ |
| | | public abstract byte[] getBytes_V1() throws UnsupportedEncodingException; |
| | | |
| | | /** |
| | | * Get the byte array representation of this Message. This uses the version |
| | | * 2 of the replication protocol (used for compatibility purpose). |
| | | * |
| | | * @return The byte array representation of this Message. |
| | | * |
| | | * @throws UnsupportedEncodingException When the encoding of the message |
| | | * failed because the UTF-8 encoding is not supported. |
| | | */ |
| | | public abstract byte[] getBytes_V23() throws UnsupportedEncodingException; |
| | | |
| | | |
| | | /** |
| | | * Get the byte array representation of this Message. This uses the version |
| | | * 4 of the replication protocol (used for compatibility purpose). |
| | | * |
| | | * @return The byte array representation of this Message. |
| | | * |
| | | * @throws UnsupportedEncodingException When the encoding of the message |
| | | * failed because the UTF-8 encoding is not supported. |
| | | */ |
| | | public abstract byte[] getBytes_V4() throws UnsupportedEncodingException; |
| | | |
| | | |
| | | /** |
| | | * Encode a list of attributes. |
| | | */ |
| | | static private byte[] encodeAttributes(List<Attribute> attributes) |
| | | { |
| | | if (attributes==null) |
| | | return new byte[0]; |
| | | try |
| | | { |
| | | ByteStringBuilder byteBuilder = new ByteStringBuilder(); |
| | | ASN1Writer writer = ASN1.getWriter(byteBuilder); |
| | | for (Attribute a : attributes) |
| | | { |
| | | new LDAPAttribute(a).write(writer); |
| | | } |
| | | return byteBuilder.toByteArray(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | // ============ |
| | | // Msg decoding |
| | | // ============ |
| | | |
| | | /** |
| | | * Decode the Header part of this Update Message, and check its type. |
| | | * |
| | | * @param types The allowed types of this Update Message. |
| | |
| | | * @throws DataFormatException if the encodedMsg does not contain a valid |
| | | * common header. |
| | | */ |
| | | public int decodeHeader(byte[] types, byte[] encodedMsg) |
| | | public int decodeHeader(byte[] types, byte[] encodedMsg) |
| | | throws DataFormatException |
| | | { |
| | | /* The message header is stored in the form : |
| | | * <operation type><protocol version><changenumber><dn><entryuuid><assured> |
| | | * <assured mode> <safe data level> |
| | | */ |
| | | { |
| | | /* first byte is the type */ |
| | | boolean foundMatchingType = false; |
| | | for (int i = 0; i < types.length; i++) |
| | | { |
| | | if (types[i] == encodedMsg[0]) |
| | | { |
| | | foundMatchingType = true; |
| | | break; |
| | | } |
| | | } |
| | | if (!foundMatchingType) |
| | | throw new DataFormatException("byte[] is not a valid update msg: " |
| | | + encodedMsg[0]); |
| | | |
| | | /* first byte is the type */ |
| | | boolean foundMatchingType = false; |
| | | for (int i = 0; i < types.length; i++) |
| | | { |
| | | if (types[i] == encodedMsg[0]) |
| | | { |
| | | foundMatchingType = true; |
| | | break; |
| | | } |
| | | } |
| | | if (!foundMatchingType) |
| | | throw new DataFormatException("byte[] is not a valid update msg: " |
| | | + encodedMsg[0]); |
| | | /* |
| | | * For older protocol version PDUs, decode the matching version header |
| | | * instead. |
| | | */ |
| | | if ((encodedMsg[0] == MSG_TYPE_ADD_V1) || |
| | | (encodedMsg[0] == MSG_TYPE_DELETE_V1) || |
| | | (encodedMsg[0] == MSG_TYPE_MODIFYDN_V1) || |
| | | (encodedMsg[0] == MSG_TYPE_MODIFY_V1)) |
| | | { |
| | | return decodeHeader_V1(encodedMsg); |
| | | } |
| | | |
| | | /* |
| | | * For older protocol version PDUs, decode the matching version header |
| | | * instead. |
| | | */ |
| | | if ((encodedMsg[0] == MSG_TYPE_ADD_V1) || |
| | | (encodedMsg[0] == MSG_TYPE_DELETE_V1) || |
| | | (encodedMsg[0] == MSG_TYPE_MODIFYDN_V1) || |
| | | (encodedMsg[0] == MSG_TYPE_MODIFY_V1)) |
| | | { |
| | | return decodeHeader_V1(encodedMsg); |
| | | } |
| | | /* read the protocol version */ |
| | | protocolVersion = (short)encodedMsg[1]; |
| | | |
| | | /* read the protocol version */ |
| | | protocolVersion = (short)encodedMsg[1]; |
| | | try |
| | | { |
| | | /* Read the changeNumber */ |
| | | int pos = 2; |
| | | int length = getNextLength(encodedMsg, pos); |
| | | String changenumberStr = new String(encodedMsg, pos, length, "UTF-8"); |
| | | pos += length + 1; |
| | | changeNumber = new ChangeNumber(changenumberStr); |
| | | |
| | | try |
| | | { |
| | | /* Read the changeNumber */ |
| | | int pos = 2; |
| | | int length = getNextLength(encodedMsg, pos); |
| | | String changenumberStr = new String(encodedMsg, pos, length, "UTF-8"); |
| | | pos += length + 1; |
| | | changeNumber = new ChangeNumber(changenumberStr); |
| | | /* Read the dn */ |
| | | length = getNextLength(encodedMsg, pos); |
| | | dn = new String(encodedMsg, pos, length, "UTF-8"); |
| | | pos += length + 1; |
| | | |
| | | /* Read the dn */ |
| | | length = getNextLength(encodedMsg, pos); |
| | | dn = new String(encodedMsg, pos, length, "UTF-8"); |
| | | pos += length + 1; |
| | | /* Read the entryuuid */ |
| | | length = getNextLength(encodedMsg, pos); |
| | | uniqueId = new String(encodedMsg, pos, length, "UTF-8"); |
| | | pos += length + 1; |
| | | |
| | | /* Read the entryuuid */ |
| | | length = getNextLength(encodedMsg, pos); |
| | | uniqueId = new String(encodedMsg, pos, length, "UTF-8"); |
| | | pos += length + 1; |
| | | /* Read the assured information */ |
| | | if (encodedMsg[pos++] == 1) |
| | | assuredFlag = true; |
| | | else |
| | | assuredFlag = false; |
| | | |
| | | /* Read the assured information */ |
| | | if (encodedMsg[pos++] == 1) |
| | | assuredFlag = true; |
| | | else |
| | | assuredFlag = false; |
| | | /* Read the assured mode */ |
| | | assuredMode = AssuredMode.valueOf(encodedMsg[pos++]); |
| | | |
| | | /* Read the assured mode */ |
| | | assuredMode = AssuredMode.valueOf(encodedMsg[pos++]); |
| | | /* Read the safe data level */ |
| | | safeDataLevel = encodedMsg[pos++]; |
| | | |
| | | /* Read the safe data level */ |
| | | safeDataLevel = encodedMsg[pos++]; |
| | | |
| | | return pos; |
| | | } catch (UnsupportedEncodingException e) |
| | | { |
| | | throw new DataFormatException("UTF-8 is not supported by this jvm."); |
| | | } catch (IllegalArgumentException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | return pos; |
| | | } catch (UnsupportedEncodingException e) |
| | | { |
| | | throw new DataFormatException("UTF-8 is not supported by this jvm."); |
| | | } catch (IllegalArgumentException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | * @return The number of bytes used by this message. |
| | | */ |
| | | public abstract int size(); |
| | | |
| | | /** |
| | | * Return the number of bytes used by the header. |
| | | * @return The number of bytes used by the header. |
| | | */ |
| | | protected int headerSize() |
| | | { |
| | | return 100; // 100 let's assume header size is 100 |
| | | } |
| | | |
| | | /** |
| | | * Set a provided list of entry attributes. |
| | | * @param entryAttrs The provided list of entry attributes. |
| | | */ |
| | | public void setEclIncludes(List<Attribute> entryAttrs) |
| | | { |
| | | this.encodedEclIncludes = encodeAttributes(entryAttrs); |
| | | } |
| | | |
| | | /** |
| | | * Returns the list of entry attributes. |
| | | * @return The list of entry attributes. |
| | | */ |
| | | public ArrayList<RawAttribute> getEclIncludes() |
| | | { |
| | | try |
| | | { |
| | | return decodeRawAttributes(this.encodedEclIncludes); |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Decode a provided byte array as a list of RawAttribute. |
| | | * @param in The provided byte array. |
| | | * @return The list of Rawattribute objects. |
| | | * @throws LDAPException when it occurs. |
| | | * @throws ASN1Exception when it occurs. |
| | | */ |
| | | public ArrayList<RawAttribute> decodeRawAttributes(byte[] in) |
| | | throws LDAPException, ASN1Exception |
| | | { |
| | | ArrayList<RawAttribute> rattr = new ArrayList<RawAttribute>(); |
| | | try |
| | | { |
| | | ByteSequenceReader reader = |
| | | ByteString.wrap(in).asReader(); |
| | | ASN1Reader asn1Reader = ASN1.getReader(reader); |
| | | // loop on attributes |
| | | while(asn1Reader.hasNextElement()) |
| | | { |
| | | rattr.add(LDAPAttribute.decode(asn1Reader)); |
| | | } |
| | | return rattr; |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Decode a provided byte array as a list of Attribute. |
| | | * @param in The provided byte array. |
| | | * @return The list of Attribute objects. |
| | | * @throws LDAPException when it occurs. |
| | | * @throws ASN1Exception when it occurs. |
| | | */ |
| | | public ArrayList<Attribute> decodeAttributes(byte[] in) |
| | | throws LDAPException, ASN1Exception |
| | | { |
| | | ArrayList<Attribute> lattr = new ArrayList<Attribute>(); |
| | | try |
| | | { |
| | | ByteSequenceReader reader = |
| | | ByteString.wrap(in).asReader(); |
| | | ASN1Reader asn1Reader = ASN1.getReader(reader); |
| | | // loop on attributes |
| | | while(asn1Reader.hasNextElement()) |
| | | { |
| | | lattr.add(LDAPAttribute.decode(asn1Reader).toAttribute()); |
| | | } |
| | | return lattr; |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | } |
| | |
| | | * |
| | | * Copyright 2009 Sun Microsystems, Inc. |
| | | */ |
| | | |
| | | package org.opends.server.replication.protocol; |
| | | |
| | | import java.util.ArrayList; |
| | |
| | | import org.opends.server.types.ByteStringBuilder; |
| | | import org.opends.server.types.LDAPException; |
| | | import org.opends.server.types.Modification; |
| | | import org.opends.server.types.RawModification; |
| | | |
| | | /** |
| | | * This class holds every common code for the modify messages (mod, moddn). |
| | |
| | | */ |
| | | public void setMods(List<Modification> mods) |
| | | { |
| | | encodedMods = modsToByte(mods); |
| | | encodedMods = encodeMods(mods); |
| | | } |
| | | |
| | | /** |
| | | * Get the Modifications associated to the UpdateMsg to the provided value. |
| | | * @throws LDAPException In case of LDAP decoding exception |
| | | * @throws ASN1Exception In case of ASN1 decoding exception |
| | | * @return the list of modifications |
| | | */ |
| | | public List<Modification> getMods() throws ASN1Exception, LDAPException |
| | | { |
| | | List<Modification> mods = new ArrayList<Modification>(); |
| | | |
| | | ASN1Reader reader = ASN1.getReader(encodedMods); |
| | | |
| | | while (reader.hasNextElement()) |
| | | mods.add((LDAPModification.decode(reader)).toModification()); |
| | | |
| | | return mods; |
| | | } |
| | | // ============ |
| | | // Msg encoding |
| | | // ============ |
| | | |
| | | /** |
| | | * Encode an ArrayList of Modification into a byte[] suitable |
| | |
| | | * @param mods the ArrayList of Modification to be encoded. |
| | | * @return The encoded modifications. |
| | | */ |
| | | protected byte[] modsToByte(List<Modification> mods) |
| | | protected byte[] encodeMods(List<Modification> mods) |
| | | { |
| | | if ((mods == null) || (mods.size() == 0)) |
| | | return new byte[0]; |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | return byteBuilder.toByteArray(); |
| | | } |
| | | |
| | | // ============ |
| | | // Msg decoding |
| | | // ============ |
| | | |
| | | /** |
| | | * Decode mods from the provided byte array. |
| | | * @param in The provided byte array. |
| | | * @throws ASN1Exception when occurs. |
| | | * @throws LDAPException when occurs. |
| | | * @return The decoded mods. |
| | | */ |
| | | protected List<Modification> decodeMods(byte[] in) |
| | | throws ASN1Exception, LDAPException |
| | | { |
| | | List<Modification> mods = new ArrayList<Modification>(); |
| | | ASN1Reader reader = ASN1.getReader(in); |
| | | while (reader.hasNextElement()) |
| | | { |
| | | mods.add((LDAPModification.decode(reader)).toModification()); |
| | | } |
| | | return mods; |
| | | } |
| | | |
| | | /** |
| | | * Decode raw mods from the provided byte array. |
| | | * @param in The provided byte array. |
| | | * @return The decoded mods. |
| | | * @throws ASN1Exception when occurs. |
| | | * @throws LDAPException when occurs. |
| | | */ |
| | | protected ArrayList<RawModification> decodeRawMods(byte[] in) |
| | | throws LDAPException, ASN1Exception |
| | | { |
| | | ArrayList<RawModification> ldapmods = new ArrayList<RawModification>(); |
| | | ASN1Reader asn1Reader = ASN1.getReader(in); |
| | | while(asn1Reader.hasNextElement()) |
| | | { |
| | | ldapmods.add(LDAPModification.decode(asn1Reader)); |
| | | } |
| | | return ldapmods; |
| | | } |
| | | |
| | | } |
| | |
| | | import java.util.zip.DataFormatException; |
| | | |
| | | import org.opends.server.core.ModifyDNOperationBasis; |
| | | import org.opends.server.protocols.asn1.ASN1; |
| | | import org.opends.server.protocols.asn1.ASN1Exception; |
| | | import org.opends.server.protocols.asn1.ASN1Reader; |
| | | import org.opends.server.protocols.internal.InternalClientConnection; |
| | | import org.opends.server.protocols.ldap.LDAPModification; |
| | | import org.opends.server.replication.common.ChangeNumber; |
| | | import org.opends.server.types.AbstractOperation; |
| | | import org.opends.server.types.ByteString; |
| | |
| | | super((OperationContext) operation.getAttachment(SYNCHROCONTEXT), |
| | | operation.getRawEntryDN().toString()); |
| | | |
| | | encodedMods = modsToByte(operation.getModifications()); |
| | | encodedMods = encodeMods(operation.getModifications()); |
| | | |
| | | ModifyDnContext ctx = |
| | | (ModifyDnContext) operation.getAttachment(SYNCHROCONTEXT); |
| | |
| | | { |
| | | this(dn, changeNumber, uid, newParentUid, deleteOldRdn, newSuperior, |
| | | newRDN); |
| | | this.encodedMods = modsToByte(mods); |
| | | this.encodedMods = encodeMods(mods); |
| | | } |
| | | |
| | | /** |
| | |
| | | public ModifyDNMsg(byte[] in) throws DataFormatException, |
| | | UnsupportedEncodingException |
| | | { |
| | | // Decode header |
| | | byte[] allowedPduTypes = new byte[2]; |
| | | allowedPduTypes[0] = MSG_TYPE_MODIFYDN; |
| | | allowedPduTypes[1] = MSG_TYPE_MODIFYDN_V1; |
| | | int pos = decodeHeader(allowedPduTypes, in); |
| | | |
| | | // protocol version has been read as part of the header |
| | | if (protocolVersion <= 3) |
| | | decodeBody_V123(in, pos); |
| | | else |
| | | { |
| | | decodeBody_V4(in, pos); |
| | | } |
| | | |
| | | if (protocolVersion==ProtocolVersion.getCurrentVersion()) |
| | | { |
| | | bytes = in; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public AbstractOperation createOperation( |
| | | InternalClientConnection connection, String newDn) |
| | | throws LDAPException, ASN1Exception |
| | | { |
| | | ModifyDNOperationBasis moddn = new ModifyDNOperationBasis(connection, |
| | | InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), null, |
| | | ByteString.valueOf(newDn), ByteString.valueOf(newRDN), |
| | | deleteOldRdn, |
| | | (newSuperior == null ? null : ByteString.valueOf(newSuperior))); |
| | | |
| | | for (Modification mod : decodeMods(encodedMods)) |
| | | { |
| | | moddn.addModification(mod); |
| | | } |
| | | |
| | | ModifyDnContext ctx = new ModifyDnContext(getChangeNumber(), getUniqueId(), |
| | | newSuperiorId); |
| | | moddn.setAttachment(SYNCHROCONTEXT, ctx); |
| | | return moddn; |
| | | } |
| | | |
| | | // ============ |
| | | // Msg Encoding |
| | | // ============ |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes_V1() throws UnsupportedEncodingException |
| | | { |
| | | byte[] byteNewRdn = newRDN.getBytes("UTF-8"); |
| | | byte[] byteNewSuperior = null; |
| | | byte[] byteNewSuperiorId = null; |
| | | |
| | | // calculate the length necessary to encode the parameters |
| | | int bodyLength = byteNewRdn.length + 1 + 1; |
| | | if (newSuperior != null) |
| | | { |
| | | byteNewSuperior = newSuperior.getBytes("UTF-8"); |
| | | bodyLength += byteNewSuperior.length + 1; |
| | | } |
| | | else |
| | | bodyLength += 1; |
| | | |
| | | if (newSuperiorId != null) |
| | | { |
| | | byteNewSuperiorId = newSuperiorId.getBytes("UTF-8"); |
| | | bodyLength += byteNewSuperiorId.length + 1; |
| | | } |
| | | else |
| | | bodyLength += 1; |
| | | |
| | | byte[] encodedMsg = encodeHeader_V1(MSG_TYPE_MODIFYDN_V1, bodyLength); |
| | | int pos = encodedMsg.length - bodyLength; |
| | | |
| | | /* put the new RDN and a terminating 0 */ |
| | | pos = addByteArray(byteNewRdn, encodedMsg, pos); |
| | | |
| | | /* put the newsuperior and a terminating 0 */ |
| | | if (newSuperior != null) |
| | | { |
| | | pos = addByteArray(byteNewSuperior, encodedMsg, pos); |
| | | } |
| | | else |
| | | encodedMsg[pos++] = 0; |
| | | |
| | | /* put the newsuperiorId and a terminating 0 */ |
| | | if (newSuperiorId != null) |
| | | { |
| | | pos = addByteArray(byteNewSuperiorId, encodedMsg, pos); |
| | | } |
| | | else |
| | | encodedMsg[pos++] = 0; |
| | | |
| | | /* put the deleteoldrdn flag */ |
| | | if (deleteOldRdn) |
| | | encodedMsg[pos++] = 1; |
| | | else |
| | | encodedMsg[pos++] = 0; |
| | | |
| | | return encodedMsg; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes_V23() throws UnsupportedEncodingException |
| | | { |
| | | // Encoding V2 / V3 |
| | | |
| | | byte[] byteNewRdn = newRDN.getBytes("UTF-8"); |
| | | byte[] byteNewSuperior = null; |
| | | byte[] byteNewSuperiorId = null; |
| | | |
| | | // calculate the length necessary to encode the parameters |
| | | int length = byteNewRdn.length + 1 + 1; |
| | | if (newSuperior != null) |
| | | { |
| | | byteNewSuperior = newSuperior.getBytes("UTF-8"); |
| | | length += byteNewSuperior.length + 1; |
| | | } |
| | | else |
| | | length += 1; |
| | | |
| | | if (newSuperiorId != null) |
| | | { |
| | | byteNewSuperiorId = newSuperiorId.getBytes("UTF-8"); |
| | | length += byteNewSuperiorId.length + 1; |
| | | } |
| | | else |
| | | length += 1; |
| | | |
| | | length += encodedMods.length + 1; |
| | | |
| | | /* encode the header in a byte[] large enough to also contain mods.. */ |
| | | byte[] encodedMsg = encodeHeader(MSG_TYPE_MODIFYDN, length); |
| | | int pos = encodedMsg.length - length; |
| | | |
| | | /* put the new RDN and a terminating 0 */ |
| | | pos = addByteArray(byteNewRdn, encodedMsg, pos); |
| | | |
| | | /* put the newsuperior and a terminating 0 */ |
| | | if (newSuperior != null) |
| | | { |
| | | pos = addByteArray(byteNewSuperior, encodedMsg, pos); |
| | | } |
| | | else |
| | | encodedMsg[pos++] = 0; |
| | | |
| | | /* put the newsuperiorId and a terminating 0 */ |
| | | if (newSuperiorId != null) |
| | | { |
| | | pos = addByteArray(byteNewSuperiorId, encodedMsg, pos); |
| | | } |
| | | else |
| | | encodedMsg[pos++] = 0; |
| | | |
| | | /* put the deleteoldrdn flag */ |
| | | if (deleteOldRdn) |
| | | encodedMsg[pos++] = 1; |
| | | else |
| | | encodedMsg[pos++] = 0; |
| | | |
| | | /* add the mods */ |
| | | if (encodedMods.length > 0) |
| | | { |
| | | pos = encodedMsg.length - (encodedMods.length + 1); |
| | | addByteArray(encodedMods, encodedMsg, pos); |
| | | } |
| | | else |
| | | encodedMsg[pos++] = 0; |
| | | |
| | | return encodedMsg; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public byte[] getBytes_V4() throws UnsupportedEncodingException |
| | | { |
| | | int bodyLength = 0; |
| | | byte[] byteNewSuperior = null; |
| | | byte[] byteNewSuperiorId = null; |
| | | |
| | | // calculate the length necessary to encode the parameters |
| | | |
| | | byte[] byteNewRdn = newRDN.getBytes("UTF-8"); |
| | | bodyLength = byteNewRdn.length + 1 + 1; |
| | | |
| | | if (newSuperior != null) |
| | | { |
| | | byteNewSuperior = newSuperior.getBytes("UTF-8"); |
| | | bodyLength += byteNewSuperior.length + 1; |
| | | } |
| | | else |
| | | bodyLength += 1; |
| | | |
| | | if (newSuperiorId != null) |
| | | { |
| | | byteNewSuperiorId = newSuperiorId.getBytes("UTF-8"); |
| | | bodyLength += byteNewSuperiorId.length + 1; |
| | | } |
| | | else |
| | | bodyLength += 1; |
| | | |
| | | byte[] byteModsLen = |
| | | String.valueOf(encodedMods.length).getBytes("UTF-8"); |
| | | bodyLength += byteModsLen.length + 1; |
| | | bodyLength += encodedMods.length + 1; |
| | | |
| | | byte[] byteEntryAttrLen = |
| | | String.valueOf(encodedEclIncludes.length).getBytes("UTF-8"); |
| | | bodyLength += byteEntryAttrLen.length + 1; |
| | | bodyLength += encodedEclIncludes.length + 1; |
| | | |
| | | /* encode the header in a byte[] large enough to also contain mods.. */ |
| | | byte[] encodedMsg = encodeHeader(MSG_TYPE_MODIFYDN, bodyLength); |
| | | |
| | | int pos = encodedMsg.length - bodyLength; |
| | | |
| | | /* put the new RDN and a terminating 0 */ |
| | | pos = addByteArray(byteNewRdn, encodedMsg, pos); |
| | | /* put the newsuperior and a terminating 0 */ |
| | | if (newSuperior != null) |
| | | { |
| | | pos = addByteArray(byteNewSuperior, encodedMsg, pos); |
| | | } |
| | | else |
| | | encodedMsg[pos++] = 0; |
| | | /* put the newsuperiorId and a terminating 0 */ |
| | | if (newSuperiorId != null) |
| | | { |
| | | pos = addByteArray(byteNewSuperiorId, encodedMsg, pos); |
| | | } |
| | | else |
| | | encodedMsg[pos++] = 0; |
| | | |
| | | /* put the deleteoldrdn flag */ |
| | | if (deleteOldRdn) |
| | | encodedMsg[pos++] = 1; |
| | | else |
| | | encodedMsg[pos++] = 0; |
| | | |
| | | pos = addByteArray(byteModsLen, encodedMsg, pos); |
| | | pos = addByteArray(encodedMods, encodedMsg, pos); |
| | | |
| | | pos = addByteArray(byteEntryAttrLen, encodedMsg, pos); |
| | | pos = addByteArray(encodedEclIncludes, encodedMsg, pos); |
| | | |
| | | return encodedMsg; |
| | | } |
| | | |
| | | // ============ |
| | | // Msg decoding |
| | | // ============ |
| | | |
| | | private void decodeBody_V123(byte[] in, int pos) |
| | | throws DataFormatException, UnsupportedEncodingException |
| | | { |
| | | /* read the newRDN |
| | | * first calculate the length then construct the string |
| | | */ |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public AbstractOperation createOperation( |
| | | InternalClientConnection connection, String newDn) |
| | | throws LDAPException, ASN1Exception |
| | | private void decodeBody_V4(byte[] in, int pos) |
| | | throws DataFormatException, UnsupportedEncodingException |
| | | { |
| | | ModifyDNOperationBasis moddn = new ModifyDNOperationBasis(connection, |
| | | InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), null, |
| | | ByteString.valueOf(newDn), ByteString.valueOf(newRDN), |
| | | deleteOldRdn, |
| | | (newSuperior == null ? null : ByteString.valueOf(newSuperior))); |
| | | /* read the newRDN |
| | | * first calculate the length then construct the string |
| | | */ |
| | | int length = getNextLength(in, pos); |
| | | newRDN = new String(in, pos, length, "UTF-8"); |
| | | pos += length + 1; |
| | | |
| | | ASN1Reader asn1Reader = ASN1.getReader(encodedMods); |
| | | while (asn1Reader.hasNextElement()) |
| | | { |
| | | moddn.addModification(LDAPModification.decode(asn1Reader) |
| | | .toModification()); |
| | | } |
| | | |
| | | ModifyDnContext ctx = new ModifyDnContext(getChangeNumber(), getUniqueId(), |
| | | newSuperiorId); |
| | | moddn.setAttachment(SYNCHROCONTEXT, ctx); |
| | | return moddn; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes() throws UnsupportedEncodingException |
| | | { |
| | | byte[] byteNewRdn = newRDN.getBytes("UTF-8"); |
| | | byte[] byteNewSuperior = null; |
| | | byte[] byteNewSuperiorId = null; |
| | | |
| | | // calculate the length necessary to encode the parameters |
| | | int length = byteNewRdn.length + 1 + 1; |
| | | if (newSuperior != null) |
| | | { |
| | | byteNewSuperior = newSuperior.getBytes("UTF-8"); |
| | | length += byteNewSuperior.length + 1; |
| | | } |
| | | /* read the newSuperior |
| | | * first calculate the length then construct the string |
| | | */ |
| | | length = getNextLength(in, pos); |
| | | if (length != 0) |
| | | newSuperior = new String(in, pos, length, "UTF-8"); |
| | | else |
| | | length += 1; |
| | | newSuperior = null; |
| | | pos += length + 1; |
| | | |
| | | if (newSuperiorId != null) |
| | | /* read the new parent Id |
| | | */ |
| | | length = getNextLength(in, pos); |
| | | if (length != 0) |
| | | newSuperiorId = new String(in, pos, length, "UTF-8"); |
| | | else |
| | | newSuperiorId = null; |
| | | pos += length + 1; |
| | | |
| | | /* get the deleteoldrdn flag */ |
| | | if (in[pos] == 0) |
| | | deleteOldRdn = false; |
| | | else |
| | | deleteOldRdn = true; |
| | | pos++; |
| | | |
| | | // Read mods len |
| | | length = getNextLength(in, pos); |
| | | int modsLen = Integer.valueOf(new String(in, pos, length,"UTF-8")); |
| | | pos += length + 1; |
| | | |
| | | // Read/Don't decode attributes |
| | | this.encodedMods = new byte[modsLen]; |
| | | try |
| | | { |
| | | byteNewSuperiorId = newSuperiorId.getBytes("UTF-8"); |
| | | length += byteNewSuperiorId.length + 1; |
| | | } |
| | | else |
| | | length += 1; |
| | | |
| | | length += encodedMods.length + 1; |
| | | |
| | | byte[] resultByteArray = encodeHeader(MSG_TYPE_MODIFYDN, length); |
| | | int pos = resultByteArray.length - length; |
| | | |
| | | /* put the new RDN and a terminating 0 */ |
| | | pos = addByteArray(byteNewRdn, resultByteArray, pos); |
| | | |
| | | /* put the newsuperior and a terminating 0 */ |
| | | if (newSuperior != null) |
| | | System.arraycopy(in, pos, encodedMods, 0, modsLen); |
| | | } catch (IndexOutOfBoundsException e) |
| | | { |
| | | pos = addByteArray(byteNewSuperior, resultByteArray, pos); |
| | | } |
| | | else |
| | | resultByteArray[pos++] = 0; |
| | | |
| | | /* put the newsuperiorId and a terminating 0 */ |
| | | if (newSuperiorId != null) |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (ArrayStoreException e) |
| | | { |
| | | pos = addByteArray(byteNewSuperiorId, resultByteArray, pos); |
| | | } |
| | | else |
| | | resultByteArray[pos++] = 0; |
| | | |
| | | /* put the deleteoldrdn flag */ |
| | | if (deleteOldRdn) |
| | | resultByteArray[pos++] = 1; |
| | | else |
| | | resultByteArray[pos++] = 0; |
| | | |
| | | /* add the mods */ |
| | | if (encodedMods.length > 0) |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (NullPointerException e) |
| | | { |
| | | pos = resultByteArray.length - (encodedMods.length + 1); |
| | | addByteArray(encodedMods, resultByteArray, pos); |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | else |
| | | resultByteArray[pos++] = 0; |
| | | pos += modsLen + 1; |
| | | |
| | | return resultByteArray; |
| | | // Read ecl attr len |
| | | length = getNextLength(in, pos); |
| | | int eclAttrLen = Integer.valueOf(new String(in, pos, length,"UTF-8")); |
| | | pos += length + 1; |
| | | |
| | | // Read/Don't decode entry attributes |
| | | encodedEclIncludes = new byte[eclAttrLen]; |
| | | try |
| | | { |
| | | System.arraycopy(in, pos, encodedEclIncludes, 0, eclAttrLen); |
| | | } catch (IndexOutOfBoundsException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (ArrayStoreException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (NullPointerException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | @Override |
| | | public int size() |
| | | { |
| | | // The MODDN message size are mainly dependent on the |
| | | // size of the DN. let's assume that they average on 100 bytes |
| | | return encodedMods.length + 100; |
| | | return encodedMods.length + newRDN.length() + |
| | | encodedEclIncludes.length + headerSize(); |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes_V1() throws UnsupportedEncodingException |
| | | { |
| | | if (bytes == null) |
| | | { |
| | | byte[] byteNewRdn = newRDN.getBytes("UTF-8"); |
| | | byte[] byteNewSuperior = null; |
| | | byte[] byteNewSuperiorId = null; |
| | | |
| | | // calculate the length necessary to encode the parameters |
| | | int length = byteNewRdn.length + 1 + 1; |
| | | if (newSuperior != null) |
| | | { |
| | | byteNewSuperior = newSuperior.getBytes("UTF-8"); |
| | | length += byteNewSuperior.length + 1; |
| | | } |
| | | else |
| | | length += 1; |
| | | |
| | | if (newSuperiorId != null) |
| | | { |
| | | byteNewSuperiorId = newSuperiorId.getBytes("UTF-8"); |
| | | length += byteNewSuperiorId.length + 1; |
| | | } |
| | | else |
| | | length += 1; |
| | | |
| | | byte[] resultByteArray = encodeHeader_V1(MSG_TYPE_MODIFYDN_V1, length); |
| | | int pos = resultByteArray.length - length; |
| | | |
| | | /* put the new RDN and a terminating 0 */ |
| | | pos = addByteArray(byteNewRdn, resultByteArray, pos); |
| | | |
| | | /* put the newsuperior and a terminating 0 */ |
| | | if (newSuperior != null) |
| | | { |
| | | pos = addByteArray(byteNewSuperior, resultByteArray, pos); |
| | | } |
| | | else |
| | | resultByteArray[pos++] = 0; |
| | | |
| | | /* put the newsuperiorId and a terminating 0 */ |
| | | if (newSuperiorId != null) |
| | | { |
| | | pos = addByteArray(byteNewSuperiorId, resultByteArray, pos); |
| | | } |
| | | else |
| | | resultByteArray[pos++] = 0; |
| | | |
| | | /* put the deleteoldrdn flag */ |
| | | if (deleteOldRdn) |
| | | resultByteArray[pos++] = 1; |
| | | else |
| | | resultByteArray[pos++] = 0; |
| | | |
| | | return resultByteArray; |
| | | } |
| | | else |
| | | { |
| | | return bytes; |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | import static org.opends.server.replication.protocol.OperationContext.*; |
| | | |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.zip.DataFormatException; |
| | | |
| | | import org.opends.server.core.ModifyOperationBasis; |
| | | import org.opends.server.protocols.ldap.LDAPModification; |
| | | import org.opends.server.protocols.internal.InternalClientConnection; |
| | | import org.opends.server.protocols.asn1.ASN1Exception; |
| | | import org.opends.server.protocols.asn1.ASN1Reader; |
| | | import org.opends.server.protocols.asn1.ASN1; |
| | | import org.opends.server.protocols.internal.InternalClientConnection; |
| | | import org.opends.server.replication.common.ChangeNumber; |
| | | import org.opends.server.types.*; |
| | | import org.opends.server.types.AbstractOperation; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.LDAPException; |
| | | import org.opends.server.types.Modification; |
| | | import org.opends.server.types.RawModification; |
| | | import org.opends.server.types.operation.PostOperationModifyOperation; |
| | | |
| | | |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.zip.DataFormatException; |
| | | |
| | | /** |
| | | * Message used to send Modify information. |
| | | */ |
| | |
| | | { |
| | | super((OperationContext) op.getAttachment(OperationContext.SYNCHROCONTEXT), |
| | | op.getRawEntryDN().toString()); |
| | | encodedMods = modsToByte(op.getModifications()); |
| | | encodedMods = encodeMods(op.getModifications()); |
| | | } |
| | | |
| | | /** |
| | |
| | | { |
| | | super(new ModifyContext(changeNumber, entryuuid), |
| | | dn.toNormalizedString()); |
| | | this.encodedMods = modsToByte(mods); |
| | | this.encodedMods = encodeMods(mods); |
| | | } |
| | | |
| | | /** |
| | |
| | | public ModifyMsg(byte[] in) throws DataFormatException, |
| | | UnsupportedEncodingException |
| | | { |
| | | bytes = in; |
| | | |
| | | // Decode header |
| | | byte[] allowedPduTypes = new byte[2]; |
| | | allowedPduTypes[0] = MSG_TYPE_MODIFY; |
| | | allowedPduTypes[1] = MSG_TYPE_MODIFY_V1; |
| | | int pos = decodeHeader(allowedPduTypes, in); |
| | | |
| | | /* Read the mods : all the remaining bytes but the terminating 0 */ |
| | | int length = in.length - pos - 1; |
| | | encodedMods = new byte[length]; |
| | | try |
| | | // protocol version has been read as part of the header |
| | | if (protocolVersion <= 3) |
| | | decodeBody_V123(in, pos); |
| | | else |
| | | decodeBody_V4(in, pos); |
| | | |
| | | if (protocolVersion==ProtocolVersion.getCurrentVersion()) |
| | | { |
| | | System.arraycopy(in, pos, encodedMods, 0, length); |
| | | } catch (IndexOutOfBoundsException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (ArrayStoreException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (NullPointerException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | bytes = in; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | UnsupportedEncodingException |
| | | { |
| | | ModifyMsg msg = new ModifyMsg(in); |
| | | |
| | | // bytes is only for current version (of the protocol) bytes ! |
| | | msg.bytes = null; |
| | | |
| | | return msg; |
| | |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes() throws UnsupportedEncodingException |
| | | { |
| | | if (bytes == null) |
| | | { |
| | | /* encode the header in a byte[] large enough to also contain the mods */ |
| | | byte[] mybytes = encodeHeader(MSG_TYPE_MODIFY, encodedMods.length + 1); |
| | | |
| | | /* add the mods */ |
| | | int pos = mybytes.length - (encodedMods.length + 1); |
| | | addByteArray(encodedMods, mybytes, pos); |
| | | |
| | | return mybytes; |
| | | } |
| | | else |
| | | { |
| | | return bytes; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public AbstractOperation createOperation(InternalClientConnection connection, |
| | | String newDn) |
| | | throws LDAPException, ASN1Exception, DataFormatException |
| | | String newDn) |
| | | throws LDAPException, ASN1Exception, DataFormatException |
| | | { |
| | | if (newDn == null) |
| | | newDn = getDn(); |
| | | |
| | | ArrayList<RawModification> ldapmods = new ArrayList<RawModification>(); |
| | | |
| | | ASN1Reader asn1Reader = ASN1.getReader(encodedMods); |
| | | while(asn1Reader.hasNextElement()) |
| | | { |
| | | ldapmods.add(LDAPModification.decode(asn1Reader)); |
| | | } |
| | | ArrayList<RawModification> ldapmods = decodeRawMods(encodedMods); |
| | | |
| | | ModifyOperationBasis mod = new ModifyOperationBasis(connection, |
| | | InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), null, |
| | | InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), null, |
| | | ByteString.valueOf(newDn), ldapmods); |
| | | ModifyContext ctx = new ModifyContext(getChangeNumber(), getUniqueId()); |
| | | mod.setAttachment(SYNCHROCONTEXT, ctx); |
| | | return mod; |
| | | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | |
| | | public int size() |
| | | { |
| | | // The ModifyMsg can be very large when added or deleted attribute |
| | | // values are very large. We therefore need to count the |
| | | // whole encoded msg. |
| | | return encodedMods.length + 100; // 100 let's assume header size is 100 |
| | | // values are very large. |
| | | // We therefore need to count the whole encoded msg. |
| | | return encodedMods.length + encodedEclIncludes.length + headerSize(); |
| | | } |
| | | |
| | | // ============ |
| | | // Msg Encoding |
| | | // ============ |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | |
| | | |
| | | return encodedMsg; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public byte[] getBytes_V23() throws UnsupportedEncodingException |
| | | { |
| | | // Encoding V2 / V3 |
| | | |
| | | /* encode the header in a byte[] large enough to also contain mods */ |
| | | byte[] encodedMsg = encodeHeader(MSG_TYPE_MODIFY, encodedMods.length + 1); |
| | | |
| | | /* add the mods */ |
| | | int pos = encodedMsg.length - (encodedMods.length + 1); |
| | | addByteArray(encodedMods, encodedMsg, pos); |
| | | |
| | | return encodedMsg; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public byte[] getBytes_V4() throws UnsupportedEncodingException |
| | | { |
| | | int bodyLength = 0; |
| | | byte[] byteModsLen = |
| | | String.valueOf(encodedMods.length).getBytes("UTF-8"); |
| | | bodyLength += byteModsLen.length + 1; |
| | | bodyLength += encodedMods.length + 1; |
| | | |
| | | byte[] byteEntryAttrLen = |
| | | String.valueOf(encodedEclIncludes.length).getBytes("UTF-8"); |
| | | bodyLength += byteEntryAttrLen.length + 1; |
| | | bodyLength += encodedEclIncludes.length + 1; |
| | | |
| | | /* encode the header in a byte[] large enough to also contain the mods */ |
| | | byte [] encodedMsg = encodeHeader(MSG_TYPE_MODIFY, bodyLength); |
| | | |
| | | int pos = encodedMsg.length - bodyLength; |
| | | pos = addByteArray(byteModsLen, encodedMsg, pos); |
| | | pos = addByteArray(encodedMods, encodedMsg, pos); |
| | | pos = addByteArray(byteEntryAttrLen, encodedMsg, pos); |
| | | pos = addByteArray(encodedEclIncludes, encodedMsg, pos); |
| | | return encodedMsg; |
| | | } |
| | | |
| | | // ============ |
| | | // Msg decoding |
| | | // ============ |
| | | |
| | | private void decodeBody_V123(byte[] in, int pos) |
| | | throws DataFormatException |
| | | { |
| | | // Read and store the mods, in encoded form |
| | | // all the remaining bytes but the terminating 0 */ |
| | | int length = in.length - pos - 1; |
| | | encodedMods = new byte[length]; |
| | | try |
| | | { |
| | | System.arraycopy(in, pos, encodedMods, 0, length); |
| | | } catch (IndexOutOfBoundsException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (ArrayStoreException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (NullPointerException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | private void decodeBody_V4(byte[] in, int pos) |
| | | throws DataFormatException, UnsupportedEncodingException |
| | | { |
| | | // Read mods len |
| | | int length = getNextLength(in, pos); |
| | | int modsLen = Integer.valueOf(new String(in, pos, length,"UTF-8")); |
| | | pos += length + 1; |
| | | |
| | | // Read/Don't decode mods |
| | | this.encodedMods = new byte[modsLen]; |
| | | try |
| | | { |
| | | System.arraycopy(in, pos, encodedMods, 0, modsLen); |
| | | } catch (IndexOutOfBoundsException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (ArrayStoreException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (NullPointerException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | pos += modsLen + 1; |
| | | |
| | | // Read ecl attr len |
| | | length = getNextLength(in, pos); |
| | | int eclAttrLen = Integer.valueOf(new String(in, pos, length,"UTF-8")); |
| | | pos += length + 1; |
| | | |
| | | // Read/Don't decode entry attributes |
| | | encodedEclIncludes = new byte[eclAttrLen]; |
| | | try |
| | | { |
| | | System.arraycopy(in, pos, encodedEclIncludes, 0, eclAttrLen); |
| | | } catch (IndexOutOfBoundsException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (ArrayStoreException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } catch (NullPointerException e) |
| | | { |
| | | throw new DataFormatException(e.getMessage()); |
| | | } |
| | | } |
| | | } |
| | |
| | | public static final short REPLICATION_PROTOCOL_V1_REAL = 49; |
| | | /** |
| | | * The constant for the second version of the replication protocol. |
| | | * Add fields in the header for assured replication. |
| | | */ |
| | | public static final short REPLICATION_PROTOCOL_V2 = 2; |
| | | |
| | | /** |
| | | * The constant for the 3rd version of the replication protocol. |
| | | * Add messages for remote ECL : not used as of today. |
| | | */ |
| | | public static final short REPLICATION_PROTOCOL_V3 = 3; |
| | | |
| | | /** |
| | | * 4th version of the replication protocol. |
| | | * Add to the body of the ADD/MOD/MODDN/DEL msgs, a list of attribute for |
| | | * ECL entry attributes. |
| | | */ |
| | | public static final short REPLICATION_PROTOCOL_V4 = 4; |
| | | |
| | | /** |
| | | * The replication protocol version used by the instance of RS/DS in this VM. |
| | | */ |
| | | private static short currentVersion = -1; |
| | |
| | | */ |
| | | public static void resetCurrentVersion() |
| | | { |
| | | currentVersion = REPLICATION_PROTOCOL_V3; |
| | | currentVersion = REPLICATION_PROTOCOL_V4; |
| | | } |
| | | |
| | | /** |
| | |
| | | msg = new WindowProbeMsg(buffer); |
| | | break; |
| | | case MSG_TYPE_TOPOLOGY: |
| | | msg = new TopologyMsg(buffer); |
| | | msg = new TopologyMsg(buffer, version); |
| | | break; |
| | | case MSG_TYPE_REPL_SERVER_MONITOR_REQUEST: |
| | | msg = new MonitorRequestMsg(buffer); |
| | |
| | | msg = new MonitorMsg(buffer, version); |
| | | break; |
| | | case MSG_TYPE_START_SESSION: |
| | | msg = new StartSessionMsg(buffer); |
| | | msg = new StartSessionMsg(buffer, version); |
| | | break; |
| | | case MSG_TYPE_CHANGE_STATUS: |
| | | msg = new ChangeStatusMsg(buffer); |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2008 Sun Microsystems, Inc. |
| | | * Copyright 2008-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.replication.protocol; |
| | | |
| | |
| | | import java.io.IOException; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.util.ArrayList; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.zip.DataFormatException; |
| | | |
| | | import org.opends.server.protocols.asn1.ASN1; |
| | | import org.opends.server.protocols.asn1.ASN1Reader; |
| | | import org.opends.server.protocols.asn1.ASN1Writer; |
| | | import org.opends.server.replication.common.AssuredMode; |
| | | import org.opends.server.replication.common.ServerStatus; |
| | | import org.opends.server.types.ByteSequenceReader; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.ByteStringBuilder; |
| | | |
| | | /** |
| | | * This message is used by DS to confirm a RS he wants to connect to him (open |
| | |
| | | // DS safe data level (relevant if assured mode is safe data) |
| | | private byte safeDataLevel = (byte) 1; |
| | | |
| | | private Set<String> eclIncludes = new HashSet<String>(); |
| | | |
| | | /** |
| | | * The protocolVersion that should be used when serializing this message. |
| | | */ |
| | | private final short protocolVersion; |
| | | |
| | | /** |
| | | * Creates a new StartSessionMsg message from its encoded form. |
| | | * |
| | | * @param in The byte array containing the encoded form of the message. |
| | | * @param version The protocol version to use to decode the msg. |
| | | * @throws java.util.zip.DataFormatException If the byte array does not |
| | | * contain a valid encoded form of the message. |
| | | */ |
| | | public StartSessionMsg(byte[] in) throws DataFormatException |
| | | public StartSessionMsg(byte[] in, short version) throws DataFormatException |
| | | { |
| | | protocolVersion = ProtocolVersion.getCurrentVersion(); |
| | | if (version <= ProtocolVersion.REPLICATION_PROTOCOL_V3) |
| | | { |
| | | decode_V23(in); |
| | | } |
| | | else |
| | | { |
| | | decode_V4(in); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Creates a new StartSessionMsg message from its encoded form. |
| | | * |
| | | * Creates a new message with the given required parameters. |
| | | * @param status Status we are starting with |
| | | * @param referralsURLs Referrals URLs to be used by peer DSs |
| | | * @param assuredFlag If assured mode is enabled or not |
| | | * @param assuredMode Assured type |
| | | * @param safeDataLevel Assured mode safe data level |
| | | * @param replicationProtocol The protocol version to use. |
| | | */ |
| | | public StartSessionMsg(ServerStatus status, List<String> referralsURLs, |
| | | boolean assuredFlag, AssuredMode assuredMode, byte safeDataLevel, |
| | | short replicationProtocol) |
| | | { |
| | | this.referralsURLs = referralsURLs; |
| | | this.status = status; |
| | | this.assuredFlag = assuredFlag; |
| | | this.assuredMode = assuredMode; |
| | | this.safeDataLevel = safeDataLevel; |
| | | this.protocolVersion = replicationProtocol; |
| | | } |
| | | |
| | | /** |
| | | * Creates a new message with the given required parameters. |
| | | * @param status Status we are starting with |
| | | * @param referralsURLs Referrals URLs to be used by peer DSs |
| | | * @param assuredFlag If assured mode is enabled or not |
| | | * @param assuredMode Assured type |
| | | * @param safeDataLevel Assured mode safe data level |
| | | */ |
| | | public StartSessionMsg(ServerStatus status, List<String> referralsURLs, |
| | | boolean assuredFlag, AssuredMode assuredMode, byte safeDataLevel) |
| | | { |
| | | this.referralsURLs = referralsURLs; |
| | | this.status = status; |
| | | this.assuredFlag = assuredFlag; |
| | | this.assuredMode = assuredMode; |
| | | this.safeDataLevel = safeDataLevel; |
| | | this.protocolVersion = ProtocolVersion.getCurrentVersion(); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new message with the given required parameters. |
| | | * Assured mode is false. |
| | | * @param status Status we are starting with |
| | | * @param referralsURLs Referrals URLs to be used by peer DSs |
| | | */ |
| | | public StartSessionMsg(ServerStatus status, List<String> referralsURLs) |
| | | { |
| | | this.referralsURLs = referralsURLs; |
| | | this.status = status; |
| | | this.assuredFlag = false; |
| | | this.protocolVersion = ProtocolVersion.getCurrentVersion(); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new message with the given required parameters. |
| | | * Assured mode is false. |
| | | * @param status Status we are starting with |
| | | * @param referralsURLs Referrals URLs to be used by peer DSs |
| | | * @param replicationProtocol The requested protocol version. |
| | | */ |
| | | public StartSessionMsg(ServerStatus status, List<String> referralsURLs, |
| | | short replicationProtocol) |
| | | { |
| | | this.referralsURLs = referralsURLs; |
| | | this.status = status; |
| | | this.assuredFlag = false; |
| | | this.protocolVersion = replicationProtocol; |
| | | } |
| | | |
| | | // ============ |
| | | // Msg encoding |
| | | // ============ |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes() |
| | | throws UnsupportedEncodingException |
| | | { |
| | | if (protocolVersion <= ProtocolVersion.REPLICATION_PROTOCOL_V3) |
| | | { |
| | | return getBytes_V23(); |
| | | } |
| | | else |
| | | { |
| | | return getBytes_V4(); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes(short reqProtocolVersion) |
| | | throws UnsupportedEncodingException |
| | | { |
| | | if (reqProtocolVersion <= ProtocolVersion.REPLICATION_PROTOCOL_V3) |
| | | { |
| | | return getBytes_V23(); |
| | | } |
| | | else |
| | | { |
| | | return getBytes_V4(); |
| | | } |
| | | } |
| | | |
| | | private byte[] getBytes_V4() |
| | | { |
| | | try |
| | | { |
| | | ByteStringBuilder byteBuilder = new ByteStringBuilder(); |
| | | ASN1Writer writer = ASN1.getWriter(byteBuilder); |
| | | |
| | | byteBuilder.append(MSG_TYPE_START_SESSION); |
| | | byteBuilder.append(status.getValue()); |
| | | byteBuilder.append(assuredFlag ? (byte) 1 : (byte) 0); |
| | | byteBuilder.append(assuredMode.getValue()); |
| | | byteBuilder.append(safeDataLevel); |
| | | |
| | | writer.writeStartSequence(); |
| | | for (String url : referralsURLs) |
| | | writer.writeOctetString(url); |
| | | writer.writeEndSequence(); |
| | | |
| | | writer.writeStartSequence(); |
| | | for (String attrDef : eclIncludes) |
| | | writer.writeOctetString(attrDef); |
| | | writer.writeEndSequence(); |
| | | |
| | | return byteBuilder.toByteArray(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | private byte[] getBytes_V23() |
| | | { |
| | | /* |
| | | * The message is stored in the form: |
| | | * <message type><status><assured flag><assured mode><safe data level> |
| | | * <list of referrals urls> |
| | | * (each referral url terminates with 0) |
| | | */ |
| | | |
| | | try |
| | | { |
| | | ByteArrayOutputStream oStream = new ByteArrayOutputStream(); |
| | | |
| | | /* Put the message type */ |
| | | oStream.write(MSG_TYPE_START_SESSION); |
| | | |
| | | // Put the status |
| | | oStream.write(status.getValue()); |
| | | |
| | | // Put the assured flag |
| | | oStream.write(assuredFlag ? (byte) 1 : (byte) 0); |
| | | |
| | | // Put assured mode |
| | | oStream.write(assuredMode.getValue()); |
| | | |
| | | // Put safe data level |
| | | oStream.write(safeDataLevel); |
| | | |
| | | // Put the referrals URLs |
| | | if (referralsURLs.size() >= 1) |
| | | { |
| | | for (String url : referralsURLs) |
| | | { |
| | | byte[] byteArrayURL = url.getBytes("UTF-8"); |
| | | oStream.write(byteArrayURL); |
| | | oStream.write(0); |
| | | } |
| | | } |
| | | return oStream.toByteArray(); |
| | | } catch (IOException e) |
| | | { |
| | | // never happens |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | // ============ |
| | | // Msg decoding |
| | | // ============ |
| | | |
| | | private void decode_V4(byte[] in) |
| | | throws DataFormatException |
| | | { |
| | | ByteSequenceReader reader = ByteString.wrap(in).asReader(); |
| | | try |
| | | { |
| | | if (reader.get() != MSG_TYPE_START_SESSION) |
| | | throw new DataFormatException("input is not a valid " + |
| | | this.getClass().getCanonicalName()); |
| | | |
| | | /* |
| | | status = ServerStatus.valueOf(asn1Reader.readOctetString().byteAt(0)); |
| | | assuredFlag = (asn1Reader.readOctetString().byteAt(0) == 1); |
| | | assuredMode=AssuredMode.valueOf((asn1Reader.readOctetString().byteAt(0))); |
| | | safeDataLevel = asn1Reader.readOctetString().byteAt(0); |
| | | */ |
| | | status = ServerStatus.valueOf(reader.get()); |
| | | assuredFlag = (reader.get() == 1); |
| | | assuredMode = AssuredMode.valueOf(reader.get()); |
| | | safeDataLevel = reader.get(); |
| | | |
| | | ASN1Reader asn1Reader = ASN1.getReader(reader); |
| | | |
| | | asn1Reader.readStartSequence(); |
| | | while(asn1Reader.hasNextElement()) |
| | | { |
| | | String s = asn1Reader.readOctetStringAsString(); |
| | | this.referralsURLs.add(s); |
| | | } |
| | | asn1Reader.readEndSequence(); |
| | | |
| | | asn1Reader.readStartSequence(); |
| | | while(asn1Reader.hasNextElement()) |
| | | { |
| | | String s = asn1Reader.readOctetStringAsString(); |
| | | this.eclIncludes.add(s); |
| | | } |
| | | asn1Reader.readEndSequence(); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | | } |
| | | } |
| | | |
| | | private void decode_V23(byte[] in) |
| | | throws DataFormatException |
| | | { |
| | | /* |
| | | * The message is stored in the form: |
| | |
| | | } |
| | | |
| | | /** |
| | | * Creates a new StartSessionMsg message with the given required parameters. |
| | | * @param status Status we are starting with |
| | | * @param referralsURLs Referrals URLs to be used by peer DSs |
| | | * @param assuredFlag If assured mode is enabled or not |
| | | * @param assuredMode Assured type |
| | | * @param safeDataLevel Assured mode safe data level |
| | | */ |
| | | public StartSessionMsg(ServerStatus status, List<String> referralsURLs, |
| | | boolean assuredFlag, AssuredMode assuredMode, byte safeDataLevel) |
| | | { |
| | | this.referralsURLs = referralsURLs; |
| | | this.status = status; |
| | | this.assuredFlag = assuredFlag; |
| | | this.assuredMode = assuredMode; |
| | | this.safeDataLevel = safeDataLevel; |
| | | } |
| | | |
| | | /** |
| | | * Creates a new StartSessionMsg message with the given required parameters. |
| | | * Assured mode is false. |
| | | * @param status Status we are starting with |
| | | * @param referralsURLs Referrals URLs to be used by peer DSs |
| | | */ |
| | | public StartSessionMsg(ServerStatus status, List<String> referralsURLs) |
| | | { |
| | | this.referralsURLs = referralsURLs; |
| | | this.status = status; |
| | | this.assuredFlag = false; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes() |
| | | { |
| | | /* |
| | | * The message is stored in the form: |
| | | * <message type><status><assured flag><assured mode><safe data level> |
| | | * <list of referrals urls> |
| | | * (each referral url terminates with 0) |
| | | */ |
| | | |
| | | try |
| | | { |
| | | ByteArrayOutputStream oStream = new ByteArrayOutputStream(); |
| | | |
| | | /* Put the message type */ |
| | | oStream.write(MSG_TYPE_START_SESSION); |
| | | |
| | | // Put the status |
| | | oStream.write(status.getValue()); |
| | | |
| | | // Put the assured flag |
| | | oStream.write(assuredFlag ? (byte) 1 : (byte) 0); |
| | | |
| | | // Put assured mode |
| | | oStream.write(assuredMode.getValue()); |
| | | |
| | | // Put safe data level |
| | | oStream.write(safeDataLevel); |
| | | |
| | | // Put the referrals URLs |
| | | if (referralsURLs.size() >= 1) |
| | | { |
| | | for (String url : referralsURLs) |
| | | { |
| | | byte[] byteArrayURL = url.getBytes("UTF-8"); |
| | | oStream.write(byteArrayURL); |
| | | oStream.write(0); |
| | | } |
| | | } |
| | | |
| | | return oStream.toByteArray(); |
| | | } catch (IOException e) |
| | | { |
| | | // never happens |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Get the list of referrals URLs. |
| | | * |
| | | * @return The list of referrals URLs. |
| | |
| | | "\nassuredFlag: " + assuredFlag + |
| | | "\nassuredMode: " + assuredMode + |
| | | "\nsafeDataLevel: " + safeDataLevel + |
| | | "\nreferralsURLs: " + urls); |
| | | "\nreferralsURLs: " + urls + |
| | | "\nEclIncludes: " + eclIncludes); |
| | | } |
| | | |
| | | /** |
| | |
| | | return safeDataLevel; |
| | | } |
| | | |
| | | /** |
| | | * Set the list of entry attributes to include in the ECL. |
| | | * @param eclIncludes The list of attributes. |
| | | */ |
| | | public void setEclIncludes(Set<String> eclIncludes) |
| | | { |
| | | if (eclIncludes != null) |
| | | this.eclIncludes = eclIncludes; |
| | | } |
| | | |
| | | /** |
| | | * Get the list of entry attributes to include in the ECL.. |
| | | * @return The list of entry attributes to include in the ECL. |
| | | */ |
| | | public Set<String> getEclIncludes() |
| | | { |
| | | return eclIncludes; |
| | | } |
| | | |
| | | } |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2007-2008 Sun Microsystems, Inc. |
| | | * Copyright 2007-2009 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.replication.protocol; |
| | | |
| | |
| | | import java.io.IOException; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.util.ArrayList; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.zip.DataFormatException; |
| | | |
| | | import org.opends.server.replication.common.AssuredMode; |
| | | import org.opends.server.replication.common.DSInfo; |
| | | import org.opends.server.replication.common.RSInfo; |
| | |
| | | private List<RSInfo> rsList = new ArrayList<RSInfo>(); |
| | | |
| | | /** |
| | | * The protocolVersion that should be used when serializing this message. |
| | | */ |
| | | private final short protocolVersion; |
| | | |
| | | /** |
| | | * Creates a new changelogInfo message from its encoded form. |
| | | * |
| | | * @param in The byte array containing the encoded form of the message. |
| | | * @param version The protocol version to use to decode the msg. |
| | | * @throws java.util.zip.DataFormatException If the byte array does not |
| | | * contain a valid encoded form of the message. |
| | | */ |
| | | public TopologyMsg(byte[] in) throws DataFormatException |
| | | public TopologyMsg(byte[] in, short version) throws DataFormatException |
| | | { |
| | | protocolVersion = ProtocolVersion.getCurrentVersion(); |
| | | decode(in, version); |
| | | } |
| | | |
| | | /** |
| | | * Creates a new message from a list of the currently connected servers. |
| | | * |
| | | * @param dsList The list of currently connected DS servers ID. |
| | | * @param rsList The list of currently connected RS servers ID. |
| | | * @param version The protocol version to use to decode the msg. |
| | | */ |
| | | public TopologyMsg(List<DSInfo> dsList, List<RSInfo> rsList, short version) |
| | | { |
| | | if (dsList != null) // null means no info, let empty list from init time |
| | | this.dsList = dsList; |
| | | if (rsList != null) // null means no info, let empty list from init time |
| | | this.rsList = rsList; |
| | | this.protocolVersion = version; |
| | | } |
| | | |
| | | /** |
| | | * Creates a new message from a list of the currently connected servers. |
| | | * |
| | | * @param dsList The list of currently connected DS servers ID. |
| | | * @param rsList The list of currently connected RS servers ID. |
| | | */ |
| | | public TopologyMsg(List<DSInfo> dsList, List<RSInfo> rsList) |
| | | { |
| | | if (dsList != null) // null means no info, let empty list from init time |
| | | this.dsList = dsList; |
| | | if (rsList != null) // null means no info, let empty list from init time |
| | | this.rsList = rsList; |
| | | this.protocolVersion = ProtocolVersion.getCurrentVersion(); |
| | | } |
| | | |
| | | // ============ |
| | | // Msg encoding |
| | | // ============ |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes() |
| | | throws UnsupportedEncodingException |
| | | { |
| | | try |
| | | { |
| | | /** |
| | | * Message has the following form: |
| | | * <pdu type><number of following DSInfo entries>[<DSInfo>]* |
| | | * <number of following RSInfo entries>[<RSInfo>]* |
| | | */ |
| | | ByteArrayOutputStream oStream = new ByteArrayOutputStream(); |
| | | |
| | | /* Put the message type */ |
| | | oStream.write(MSG_TYPE_TOPOLOGY); |
| | | |
| | | // Put number of following DS info entries |
| | | oStream.write((byte)dsList.size()); |
| | | |
| | | // Put DS info |
| | | for (DSInfo dsInfo : dsList) |
| | | { |
| | | // Put DS id |
| | | byte[] byteServerId = |
| | | String.valueOf(dsInfo.getDsId()).getBytes("UTF-8"); |
| | | oStream.write(byteServerId); |
| | | oStream.write(0); |
| | | // Put RS id |
| | | byteServerId = |
| | | String.valueOf(dsInfo.getRsId()).getBytes("UTF-8"); |
| | | oStream.write(byteServerId); |
| | | oStream.write(0); |
| | | // Put the generation id |
| | | oStream.write(String.valueOf(dsInfo.getGenerationId()). |
| | | getBytes("UTF-8")); |
| | | oStream.write(0); |
| | | // Put DS status |
| | | oStream.write(dsInfo.getStatus().getValue()); |
| | | // Put DS assured flag |
| | | oStream.write(dsInfo.isAssured() ? (byte) 1 : (byte) 0); |
| | | // Put DS assured mode |
| | | oStream.write(dsInfo.getAssuredMode().getValue()); |
| | | // Put DS safe data level |
| | | oStream.write(dsInfo.getSafeDataLevel()); |
| | | // Put DS group id |
| | | oStream.write(dsInfo.getGroupId()); |
| | | |
| | | List<String> refUrls = dsInfo.getRefUrls(); |
| | | // Put number of following URLs as a byte |
| | | oStream.write(refUrls.size()); |
| | | for (String url : refUrls) |
| | | { |
| | | // Write the url and a 0 terminating byte |
| | | oStream.write(url.getBytes("UTF-8")); |
| | | oStream.write(0); |
| | | } |
| | | |
| | | if (protocolVersion >= ProtocolVersion.REPLICATION_PROTOCOL_V4) |
| | | { |
| | | Set<String> attrs = dsInfo.getEclIncludes(); |
| | | oStream.write(attrs.size()); |
| | | for (String attr : attrs) |
| | | { |
| | | oStream.write(attr.getBytes("UTF-8")); |
| | | oStream.write(0); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // Put number of following RS info entries |
| | | oStream.write((byte)rsList.size()); |
| | | |
| | | // Put RS info |
| | | for (RSInfo rsInfo : rsList) |
| | | { |
| | | // Put RS id |
| | | byte[] byteServerId = |
| | | String.valueOf(rsInfo.getId()).getBytes("UTF-8"); |
| | | oStream.write(byteServerId); |
| | | oStream.write(0); |
| | | // Put the generation id |
| | | oStream.write(String.valueOf(rsInfo.getGenerationId()). |
| | | getBytes("UTF-8")); |
| | | oStream.write(0); |
| | | // Put DS group id |
| | | oStream.write(rsInfo.getGroupId()); |
| | | } |
| | | |
| | | return oStream.toByteArray(); |
| | | } catch (IOException e) |
| | | { |
| | | // never happens |
| | | return null; |
| | | } |
| | | |
| | | } |
| | | |
| | | // ============ |
| | | // Msg decoding |
| | | // ============ |
| | | |
| | | private void decode(byte[] in, short version) |
| | | throws DataFormatException |
| | | { |
| | | try |
| | | { |
| | |
| | | nRead++; |
| | | } |
| | | |
| | | Set<String> attrs = new HashSet<String>(); |
| | | if (version>=ProtocolVersion.REPLICATION_PROTOCOL_V4) |
| | | { |
| | | byte nAttrs = in[pos++]; |
| | | nRead = 0; |
| | | /* Read attrs until expected number read */ |
| | | while ((nRead != nAttrs) && |
| | | (pos < in.length) //security |
| | | ) |
| | | { |
| | | length = getNextLength(in, pos); |
| | | String attr = new String(in, pos, length, "UTF-8"); |
| | | attrs.add(attr); |
| | | pos += |
| | | length + 1; |
| | | nRead++; |
| | | } |
| | | } |
| | | |
| | | /* Now create DSInfo and store it in list */ |
| | | |
| | | DSInfo dsInfo = new DSInfo(dsId, rsId, generationId, status, |
| | | assuredFlag, assuredMode, safeDataLevel, groupId, refUrls); |
| | | assuredFlag, assuredMode, safeDataLevel, groupId, refUrls, attrs); |
| | | dsList.add(dsInfo); |
| | | |
| | | nDsInfo--; |
| | |
| | | { |
| | | throw new DataFormatException("UTF-8 is not supported by this jvm."); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * Creates a new ReplServerInfo message from a list of the currently |
| | | * connected servers. |
| | | * |
| | | * @param dsList The list of currently connected DS servers ID. |
| | | * @param rsList The list of currently connected RS servers ID. |
| | | */ |
| | | public TopologyMsg(List<DSInfo> dsList, List<RSInfo> rsList) |
| | | { |
| | | if (dsList != null) // null means no info, let empty list from init time |
| | | this.dsList = dsList; |
| | | if (rsList != null) // null means no info, let empty list from init time |
| | | this.rsList = rsList; |
| | | } |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | @Override |
| | | public byte[] getBytes() |
| | | { |
| | | try |
| | | { |
| | | /** |
| | | * Message has the following form: |
| | | * <pdu type><number of following DSInfo entries>[<DSInfo>]* |
| | | * <number of following RSInfo entries>[<RSInfo>]* |
| | | */ |
| | | ByteArrayOutputStream oStream = new ByteArrayOutputStream(); |
| | | |
| | | /* Put the message type */ |
| | | oStream.write(MSG_TYPE_TOPOLOGY); |
| | | |
| | | // Put number of following DS info entries |
| | | oStream.write((byte)dsList.size()); |
| | | |
| | | // Put DS info |
| | | for (DSInfo dsInfo : dsList) |
| | | { |
| | | // Put DS id |
| | | byte[] byteServerId = |
| | | String.valueOf(dsInfo.getDsId()).getBytes("UTF-8"); |
| | | oStream.write(byteServerId); |
| | | oStream.write(0); |
| | | // Put RS id |
| | | byteServerId = |
| | | String.valueOf(dsInfo.getRsId()).getBytes("UTF-8"); |
| | | oStream.write(byteServerId); |
| | | oStream.write(0); |
| | | // Put the generation id |
| | | oStream.write(String.valueOf(dsInfo.getGenerationId()). |
| | | getBytes("UTF-8")); |
| | | oStream.write(0); |
| | | // Put DS status |
| | | oStream.write(dsInfo.getStatus().getValue()); |
| | | // Put DS assured flag |
| | | oStream.write(dsInfo.isAssured() ? (byte) 1 : (byte) 0); |
| | | // Put DS assured mode |
| | | oStream.write(dsInfo.getAssuredMode().getValue()); |
| | | // Put DS safe data level |
| | | oStream.write(dsInfo.getSafeDataLevel()); |
| | | // Put DS group id |
| | | oStream.write(dsInfo.getGroupId()); |
| | | |
| | | List<String> refUrls = dsInfo.getRefUrls(); |
| | | // Put number of following URLs as a byte |
| | | oStream.write(refUrls.size()); |
| | | for (String url : refUrls) |
| | | { |
| | | // Write the url and a 0 terminating byte |
| | | oStream.write(url.getBytes("UTF-8")); |
| | | oStream.write(0); |
| | | } |
| | | } |
| | | |
| | | // Put number of following RS info entries |
| | | oStream.write((byte)rsList.size()); |
| | | |
| | | // Put RS info |
| | | for (RSInfo rsInfo : rsList) |
| | | { |
| | | // Put RS id |
| | | byte[] byteServerId = |
| | | String.valueOf(rsInfo.getId()).getBytes("UTF-8"); |
| | | oStream.write(byteServerId); |
| | | oStream.write(0); |
| | | // Put the generation id |
| | | oStream.write(String.valueOf(rsInfo.getGenerationId()). |
| | | getBytes("UTF-8")); |
| | | oStream.write(0); |
| | | // Put DS group id |
| | | oStream.write(rsInfo.getGroupId()); |
| | | } |
| | | |
| | | return oStream.toByteArray(); |
| | | } catch (IOException e) |
| | | { |
| | | // never happens |
| | | return null; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.zip.DataFormatException; |
| | | |
| | | import org.opends.messages.Message; |
| | |
| | | private AssuredMode assuredMode = AssuredMode.SAFE_DATA_MODE; |
| | | // DS safe data level (relevant if assured mode is safe data) |
| | | private byte safeDataLevel = (byte) -1; |
| | | private Set<String> eclIncludes = new HashSet<String>(); |
| | | |
| | | /** |
| | | * Creates a new data server handler. |
| | |
| | | public DSInfo toDSInfo() |
| | | { |
| | | DSInfo dsInfo = new DSInfo(serverId, replicationServerId, generationId, |
| | | status, assuredFlag, assuredMode, safeDataLevel, groupId, refUrls); |
| | | status, assuredFlag, assuredMode, safeDataLevel, groupId, refUrls, |
| | | eclIncludes); |
| | | |
| | | return dsInfo; |
| | | } |
| | |
| | | this.assuredFlag = startSessionMsg.isAssured(); |
| | | this.assuredMode = startSessionMsg.getAssuredMode(); |
| | | this.safeDataLevel = startSessionMsg.getSafeDataLevel(); |
| | | this.eclIncludes = startSessionMsg.getEclIncludes(); |
| | | |
| | | /* |
| | | * If we have already a generationID set for the domain |
| | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | |
| | | import org.opends.server.admin.std.server.MonitorProviderCfg; |
| | | import org.opends.server.api.MonitorProvider; |
| | | import org.opends.server.config.ConfigException; |
| | |
| | | // DS safe data level (relevant if assured mode is safe data) |
| | | private byte safeDataLevel = (byte) -1; |
| | | |
| | | private Set<String> eclInclude = new HashSet<String>(); |
| | | |
| | | /** |
| | | * Creates a new LighweightServerHandler with the provided serverid, connected |
| | | * to the remote Replication Server represented by replServerHandler. |
| | |
| | | * @param assuredFlag The assured flag of the remote DS |
| | | * @param assuredMode The assured mode of the remote DS |
| | | * @param safeDataLevel The safe data level of the remote DS |
| | | * @param eclInclude The list of entry attributes to be added to the ECL. |
| | | */ |
| | | public LightweightServerHandler(ReplicationServerHandler replServerHandler, |
| | | short replicationServerId, short serverId, long generationId, byte groupId, |
| | | ServerStatus status, List<String> refUrls, boolean assuredFlag, |
| | | AssuredMode assuredMode, byte safeDataLevel) |
| | | AssuredMode assuredMode, byte safeDataLevel, Set<String> eclInclude) |
| | | { |
| | | super("Server Handler"); |
| | | this.replServerHandler = replServerHandler; |
| | |
| | | this.assuredFlag = assuredFlag; |
| | | this.assuredMode = assuredMode; |
| | | this.safeDataLevel = safeDataLevel; |
| | | this.eclInclude = eclInclude; |
| | | |
| | | if (debugEnabled()) |
| | | TRACER.debugInfo( |
| | |
| | | public DSInfo toDSInfo() |
| | | { |
| | | DSInfo dsInfo = new DSInfo(serverId, replicationServerId, generationId, |
| | | status, assuredFlag, assuredMode, safeDataLevel, groupId, refUrls); |
| | | status, assuredFlag, assuredMode, safeDataLevel, groupId, refUrls, |
| | | eclInclude); |
| | | |
| | | return dsInfo; |
| | | } |
| | |
| | | import org.opends.server.replication.common.ServerStatus; |
| | | import org.opends.server.replication.common.StatusMachineEvent; |
| | | import org.opends.server.replication.protocol.AckMsg; |
| | | import org.opends.server.replication.protocol.ChangeTimeHeartbeatMsg; |
| | | import org.opends.server.replication.protocol.ChangeStatusMsg; |
| | | import org.opends.server.replication.protocol.ChangeTimeHeartbeatMsg; |
| | | import org.opends.server.replication.protocol.DoneMsg; |
| | | import org.opends.server.replication.protocol.EntryMsg; |
| | | import org.opends.server.replication.protocol.ErrorMsg; |
| | |
| | | return eligibleCN; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Processes a ChangeTimeHeartbeatMsg received, by storing the CN (timestamp) |
| | | * value received, and forwarding the message to the other RSes. |
| | |
| | | if (senderHandler.isDataServer()) |
| | | { |
| | | // If we are the first replication server warned, |
| | | // then forwards the reset message to the remote replication servers |
| | | // then forwards the message to the remote replication servers |
| | | for (ReplicationServerHandler rsHandler : replicationServers.values()) |
| | | { |
| | | try |
| | |
| | | serverId, dsInfo.getDsId(), dsInfo.getGenerationId(), |
| | | dsInfo.getGroupId(), dsInfo.getStatus(), dsInfo.getRefUrls(), |
| | | dsInfo.isAssured(), dsInfo.getAssuredMode(), |
| | | dsInfo.getSafeDataLevel()); |
| | | dsInfo.getSafeDataLevel(), |
| | | dsInfo.getEclIncludes()); |
| | | lsh.startHandler(); |
| | | remoteDirectoryServers.put(lsh.getServerId(), lsh); |
| | | } |
| | |
| | | */ |
| | | package org.opends.server.replication.server; |
| | | |
| | | import org.opends.messages.Message; |
| | | |
| | | import static org.opends.server.loggers.ErrorLogger.logError; |
| | | import static org.opends.messages.ReplicationMessages.*; |
| | | import static org.opends.server.loggers.debug.DebugLogger.*; |
| | | import static org.opends.server.loggers.ErrorLogger.logError; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | | import static org.opends.server.loggers.debug.DebugLogger.getTracer; |
| | | import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString; |
| | | |
| | | |
| | | import java.io.IOException; |
| | | |
| | | import org.opends.messages.Message; |
| | | import org.opends.server.api.DirectoryThread; |
| | | import org.opends.server.replication.protocol.AckMsg; |
| | | import org.opends.server.replication.protocol.DoneMsg; |
| | | import org.opends.server.replication.protocol.EntryMsg; |
| | | import org.opends.server.replication.protocol.ErrorMsg; |
| | | import org.opends.server.replication.protocol.ResetGenerationIdMsg; |
| | | import org.opends.server.replication.protocol.InitializeRequestMsg; |
| | | import org.opends.server.replication.protocol.InitializeTargetMsg; |
| | | import org.opends.server.replication.protocol.ProtocolSession; |
| | | import org.opends.server.replication.protocol.ReplicationMsg; |
| | | import org.opends.server.replication.protocol.UpdateMsg; |
| | | import org.opends.server.replication.protocol.WindowMsg; |
| | | import org.opends.server.replication.protocol.WindowProbeMsg; |
| | | import org.opends.server.replication.protocol.TopologyMsg; |
| | | import org.opends.server.replication.protocol.MonitorMsg; |
| | | import org.opends.server.replication.protocol.MonitorRequestMsg; |
| | | import org.opends.server.replication.protocol.ChangeTimeHeartbeatMsg; |
| | | import org.opends.server.loggers.debug.DebugTracer; |
| | | import org.opends.server.replication.common.ServerStatus; |
| | | import org.opends.server.replication.protocol.ChangeStatusMsg; |
| | | import org.opends.server.replication.protocol. |
| | | NotSupportedOldVersionPDUException; |
| | | import org.opends.server.replication.protocol.*; |
| | | |
| | | /** |
| | | * This class implement the part of the replicationServer that is reading |
| | |
| | | domain.isAssured(), |
| | | domain.getAssuredMode(), |
| | | domain.getAssuredSdLevel()); |
| | | startSessionMsg.setEclIncludes( |
| | | domain.getEclInclude()); |
| | | } else |
| | | { |
| | | startSessionMsg = |
| | |
| | | |
| | | private boolean debugEnabled() |
| | | { |
| | | return false; |
| | | return true; |
| | | } |
| | | |
| | | private static final void debugInfo(String s) |
| | |
| | | rsList = topoMsg.getRsList(); |
| | | } |
| | | } |
| | | if (domain != null) |
| | | { |
| | | for (DSInfo info : dsList) |
| | | { |
| | | for (String attr : info.getEclIncludes()) |
| | | { |
| | | domain.addEclInclude(attr); |
| | | } |
| | | } |
| | | if (debugEnabled()) |
| | | { |
| | | TRACER.debugInfo("domain: " + domain.getServiceID() + |
| | | " EclIncludes" + domain.getEclInclude()); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Check if the broker could not find any Replication Server and therefore |
| | | * connection attempt failed. |
| | |
| | | import java.net.SocketTimeoutException; |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.HashSet; |
| | | import java.util.Iterator; |
| | | import java.util.List; |
| | | import java.util.SortedMap; |
| | |
| | | private Map<Short, ServerState> replicaStates = |
| | | new HashMap<Short, ServerState>(); |
| | | |
| | | Set<String> cfgEclIncludes = new HashSet<String>(); |
| | | Set<String> eClIncludes = new HashSet<String>(); |
| | | |
| | | /** |
| | | * Returns the {@link ChangeNumberGenerator} that will be used to |
| | | * generate {@link ChangeNumber} for this domain. |
| | |
| | | else |
| | | return 0; |
| | | } |
| | | |
| | | /** |
| | | * Add an attribute to the list of attributes to include in the ECL. |
| | | * @param attribute The attribute to add. |
| | | */ |
| | | synchronized public void addEclInclude(String attribute) |
| | | { |
| | | eClIncludes.add(attribute); |
| | | } |
| | | |
| | | /** |
| | | * Get the list of attributes to include in the ECL. |
| | | * @return The list of attributes. |
| | | */ |
| | | public Set<String> getEclInclude() |
| | | { |
| | | return eClIncludes; |
| | | } |
| | | |
| | | /** |
| | | * Set the list of attributes to include in the ECL. |
| | | * @param eclIncludes The list of attributes. |
| | | */ |
| | | protected void setCfgEclInclude(Set<String> eclIncludes) |
| | | { |
| | | this.cfgEclIncludes = eclIncludes; |
| | | this.eClIncludes = eclIncludes; |
| | | } |
| | | } |
| | |
| | | stream.writeOctetString(value); |
| | | } |
| | | } |
| | | stream.writeEndSequence(); |
| | | |
| | | stream.writeEndSet(); |
| | | stream.writeEndSequence(); |
| | | } |
| | | |
| | |
| | | import org.opends.server.replication.protocol.UpdateMsg; |
| | | import org.opends.server.replication.server.ReplicationServer; |
| | | import org.opends.server.types.Attribute; |
| | | import org.opends.server.types.AttributeBuilder; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.Attributes; |
| | |
| | | // Map the addMsg to an LDIF string for the 'changes' attribute |
| | | String LDIFchanges = addMsgToLDIFString(addMsg); |
| | | |
| | | ArrayList<RawAttribute> eclAttributes = addMsg.getEclIncludes(); |
| | | |
| | | clEntry = createChangelogEntry( |
| | | eclmsg.getServiceId(), |
| | | eclmsg.getCookie().toString(), |
| | |
| | | LDIFchanges, // entry as created (in LDIF format) |
| | | addMsg.getUniqueId(), |
| | | null, // real time current entry |
| | | null, // real time attrs names |
| | | null, // hist entry attributes |
| | | eclAttributes, // entry attributes |
| | | eclmsg.getDraftChangeNumber(), |
| | | "add"); |
| | | |
| | |
| | | (ModifyOperation)modMsg.createOperation(conn); |
| | | String LDIFchanges = modToLDIF(modifyOperation.getModifications()); |
| | | |
| | | // TODO:ECL Hist entry attributes |
| | | // ArrayList<RawAttribute> attributes = modMsg.getEntryAttributes(); |
| | | ArrayList<RawAttribute> eclAttributes = modMsg.getEclIncludes(); |
| | | |
| | | clEntry = createChangelogEntry( |
| | | eclmsg.getServiceId(), |
| | | eclmsg.getCookie().toString(), |
| | |
| | | LDIFchanges, |
| | | modMsg.getUniqueId(), |
| | | null, // real time current entry |
| | | null, // real time attrs names |
| | | null, // hist entry attributes |
| | | eclAttributes, // entry attributes |
| | | eclmsg.getDraftChangeNumber(), |
| | | "modify"); |
| | | "modify"); |
| | | |
| | | } |
| | | catch(Exception e) |
| | |
| | | { |
| | | ModifyDNMsg modDNMsg = (ModifyDNMsg)msg; |
| | | |
| | | ArrayList<RawAttribute> eclAttributes = modDNMsg.getEclIncludes(); |
| | | |
| | | clEntry = createChangelogEntry( |
| | | eclmsg.getServiceId(), |
| | | eclmsg.getCookie().toString(), |
| | |
| | | null, |
| | | modDNMsg.getUniqueId(), |
| | | null, // real time current entry |
| | | null, // real time attrs names |
| | | null, // hist entry attributes |
| | | eclAttributes, // entry attributes |
| | | eclmsg.getDraftChangeNumber(), |
| | | "modrdn"); |
| | | "modrdn"); |
| | | |
| | | Attribute a = Attributes.create("newrdn", modDNMsg.getNewRDN()); |
| | | clEntry.addAttribute(a, null); |
| | |
| | | else if (msg instanceof DeleteMsg) |
| | | { |
| | | DeleteMsg delMsg = (DeleteMsg)msg; |
| | | /* TODO:ECL Entry attributes for DEL op |
| | | ArrayList<RawAttribute> rattributes = new ArrayList<RawAttribute>(); |
| | | ArrayList<RawAttribute> rattributes = delMsg.getEntryAttributes(); |
| | | // Map the entry attributes of the DelMsg to an LDIF string |
| | | // for the 'deletedentryattributes' attribute of the CL entry |
| | | String delAttrs = delMsgToLDIFString(rattributes); |
| | | */ |
| | | |
| | | ArrayList<RawAttribute> eclAttributes = delMsg.getEclIncludes(); |
| | | |
| | | clEntry = createChangelogEntry( |
| | | eclmsg.getServiceId(), |
| | | eclmsg.getCookie().toString(), |
| | | DN.decode(delMsg.getDn()), |
| | | delMsg.getChangeNumber(), |
| | | null, |
| | | null, // no changes |
| | | delMsg.getUniqueId(), |
| | | null, |
| | | null, |
| | | null, //rattributes, |
| | | eclAttributes, // entry attributes |
| | | eclmsg.getDraftChangeNumber(), |
| | | "delete"); |
| | | "delete"); |
| | | } |
| | | return clEntry; |
| | | } |
| | |
| | | * @param clearLDIFchanges The provided LDIF changes for ADD and MODIFY |
| | | * @param targetUUID The provided targetUUID. |
| | | * @param entry The provided related current entry. |
| | | * @param targetAttrNames The provided list of attributes names that should |
| | | * be read from the entry (real time values) |
| | | * @param histEntryAttributes TODO:ECL Adress hist entry attributes |
| | | * @param draftChangenumber The provided draft change number (integer) |
| | | * @param changetype The provided change type (add, ...) |
| | |
| | | String clearLDIFchanges, |
| | | String targetUUID, |
| | | Entry entry, |
| | | List<String> targetAttrNames, |
| | | List<RawAttribute> histEntryAttributes, |
| | | int draftChangenumber, |
| | | String changetype) |
| | |
| | | |
| | | if (clearLDIFchanges != null) |
| | | { |
| | | if (changetype.equalsIgnoreCase("delete")) |
| | | { |
| | | a = Attributes.create("clearDeletedEntryAttrs", clearLDIFchanges); |
| | | } |
| | | attrList = new ArrayList<Attribute>(1); |
| | | attrList.add(a); |
| | | operationalAttrs.put(a.getAttributeType(), attrList); |
| | | if((attributeType = |
| | | DirectoryServer.getAttributeType("changes")) == null) |
| | | attributeType = |
| | | DirectoryServer.getDefaultAttributeType("changes"); |
| | | |
| | | if (changetype.equalsIgnoreCase("delete")) |
| | | { |
| | | a = Attributes.create("deletedentryattrs", |
| | | clearLDIFchanges + "\n"); // force base64 |
| | | } |
| | | else |
| | | { |
| | | if((attributeType = |
| | | DirectoryServer.getAttributeType("changes")) == null) |
| | | attributeType = |
| | | DirectoryServer.getDefaultAttributeType("changes"); |
| | | a = Attributes.create(attributeType, clearLDIFchanges + "\n"); |
| | | // force base64 |
| | | } |
| | | a = Attributes.create(attributeType, clearLDIFchanges + "\n"); |
| | | // force base64 |
| | | attrList = new ArrayList<Attribute>(1); |
| | | attrList.add(a); |
| | | if(attributeType.isOperational()) |
| | |
| | | else |
| | | uAttrs.put(attributeType, attrList); |
| | | |
| | | // entryAttribute version |
| | | /* |
| | | if (targetAttrNames != null) |
| | | { |
| | | String sEntryAttrs = null; |
| | | for (String attrName : targetAttrNames) |
| | | { |
| | | List<Attribute> attrs = entry.getAttribute(attrName); |
| | | for (Attribute attr : attrs) |
| | | { |
| | | if (sEntryAttrs==null) |
| | | sEntryAttrs=""; |
| | | else |
| | | sEntryAttrs+=";"; |
| | | sEntryAttrs += attr.toString(); |
| | | } |
| | | } |
| | | if (sEntryAttrs!=null) |
| | | { |
| | | a = Attributes.create("entryAttributes", sEntryAttrs); |
| | | attrList = new ArrayList<Attribute>(1); |
| | | attrList.add(a); |
| | | uAttrs.put(a.getAttributeType(), attrList); |
| | | } |
| | | } |
| | | */ |
| | | |
| | | /* |
| | | if (targetAttrNames != null) |
| | | { |
| | | for (String attrName : targetAttrNames) |
| | | { |
| | | String newName = "target"+attrName; |
| | | List<Attribute> attrs = entry.getAttribute(attrName); |
| | | for (Attribute aa : attrs) |
| | | { |
| | | AttributeBuilder builder = new AttributeBuilder( |
| | | DirectoryServer.getDefaultAttributeType(newName)); |
| | | builder.setOptions(aa.getOptions()); |
| | | builder.addAll(aa); |
| | | attrList = new ArrayList<Attribute>(1); |
| | | attrList.add(builder.toAttribute()); |
| | | uAttrs.put(aa.getAttributeType(), attrList); |
| | | } |
| | | } |
| | | } |
| | | */ |
| | | /* TODO: Implement entry attributes historical values |
| | | if (histEntryAttributes != null) |
| | | { |
| | | for (RawAttribute rea : histEntryAttributes) |
| | | for (RawAttribute ra : histEntryAttributes) |
| | | { |
| | | // uAttrs.put(ea.getAttributeType(), null); |
| | | // FIXME: ERRONEOUS TYPING !!!!!!!!!!!!! |
| | | try |
| | | { |
| | | String newName = "target"+rea.getAttributeType(); |
| | | AttributeType nat=DirectoryServer.getDefaultAttributeType(newName); |
| | | rea.setAttributeType(newName); |
| | | String eclName = "target" + ra.getAttributeType().toLowerCase(); |
| | | AttributeBuilder builder = new AttributeBuilder( |
| | | DirectoryServer.getDefaultAttributeType(eclName)); |
| | | AttributeType at = builder.getAttributeType(); |
| | | builder.setOptions(ra.toAttribute().getOptions()); |
| | | builder.addAll(ra.toAttribute()); |
| | | attrList = new ArrayList<Attribute>(1); |
| | | attrList.add(rea.toAttribute()); |
| | | uAttrs.put(nat, attrList); |
| | | attrList.add(builder.toAttribute()); |
| | | uAttrs.put(at, attrList); |
| | | } |
| | | catch(Exception e) |
| | | { |
| | |
| | | } |
| | | } |
| | | } |
| | | */ |
| | | |
| | | // at the end build the CL entry to be returned |
| | | Entry cle = new Entry( |
| | |
| | | package org.opends.server.replication; |
| | | |
| | | import static org.opends.server.TestCaseUtils.TEST_ROOT_DN_STRING; |
| | | import static org.opends.server.loggers.ErrorLogger.logError; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | | import static org.opends.server.loggers.debug.DebugLogger.getTracer; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | | import static org.opends.server.replication.protocol.OperationContext.SYNCHROCONTEXT; |
| | | import static org.opends.server.util.StaticUtils.createEntry; |
| | | import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString; |
| | |
| | | import java.net.ServerSocket; |
| | | import java.net.Socket; |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.Iterator; |
| | | import java.util.LinkedHashSet; |
| | | import java.util.LinkedList; |
| | | import java.util.List; |
| | | import java.util.NoSuchElementException; |
| | | import java.util.Set; |
| | | import java.util.SortedSet; |
| | | import java.util.TreeSet; |
| | | |
| | | import org.opends.messages.Category; |
| | | import org.opends.messages.Message; |
| | | import org.opends.messages.Severity; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.api.Backend; |
| | | import org.opends.server.api.ConnectionHandler; |
| | |
| | | import org.opends.server.controls.PersistentSearchChangeType; |
| | | import org.opends.server.controls.PersistentSearchControl; |
| | | import org.opends.server.core.AddOperationBasis; |
| | | import org.opends.server.core.DeleteOperationBasis; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.core.ModifyDNOperationBasis; |
| | | import org.opends.server.core.ModifyOperationBasis; |
| | | import org.opends.server.loggers.debug.DebugTracer; |
| | | import org.opends.server.plugins.InvocationCounterPlugin; |
| | | import org.opends.server.protocols.asn1.ASN1Exception; |
| | |
| | | import org.opends.server.replication.protocol.StartECLSessionMsg; |
| | | import org.opends.server.replication.protocol.UpdateMsg; |
| | | import org.opends.server.replication.server.DraftCNDbHandler; |
| | | import org.opends.server.replication.server.ExternalChangeLogSessionImpl; |
| | | import org.opends.server.replication.server.ReplServerFakeConfiguration; |
| | | import org.opends.server.replication.server.ReplicationServer; |
| | | import org.opends.server.replication.server.ReplicationServerDomain; |
| | |
| | | import org.opends.server.tools.LDAPSearch; |
| | | import org.opends.server.tools.LDAPWriter; |
| | | import org.opends.server.types.Attribute; |
| | | import org.opends.server.types.AttributeBuilder; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.Attributes; |
| | | import org.opends.server.types.ByteString; |
| | |
| | | private static final String TEST_ROOT_DN_STRING2 = "o=test2"; |
| | | private static final String TEST_BACKEND_ID2 = "test2"; |
| | | |
| | | private static final String TEST_ROOT_DN_STRING3 = "o=test3"; |
| | | private static final String TEST_BACKEND_ID3 = "test3"; |
| | | |
| | | // The LDAPStatistics object associated with the LDAP connection handler. |
| | | private LDAPStatistics ldapStatistics; |
| | | |
| | |
| | | @Test(enabled=true) |
| | | public void ECLReplicationServerTest() |
| | | { |
| | | // -- |
| | | // *********************************************** |
| | | // First set of test are in the cookie mode |
| | | // *********************************************** |
| | | |
| | | // Test that private backend is excluded from ECL |
| | | ECLOnPrivateBackend();replicationServer.clearDb(); |
| | |
| | | // TODO:ECL Test SEARCH abandon and check everything shutdown and cleaned |
| | | // TODO:ECL Test PSEARCH abandon and check everything shutdown and cleaned |
| | | // TODO:ECL Test invalid DN in cookie returns UNWILLING + message |
| | | // TODO:ECL Test notif control returned contains the cookie |
| | | // TODO:ECL Test the attributes list and values returned in ECL entries |
| | | // TODO:ECL Test search -s base, -s one |
| | | |
| | |
| | | // optimize the request. |
| | | ECLFilterTest(); |
| | | |
| | | // -- |
| | | // *********************************************** |
| | | // Second set of test are in the draft compat mode |
| | | // *********************************************** |
| | | |
| | | // Empty replication changelog |
| | | ECLCompatEmpty(); |
| | |
| | | // Test simultaneous persistent searches in draft compat mode. |
| | | ECLSimultaneousPsearches();replicationServer.clearDb(); |
| | | |
| | | // *********************************************** |
| | | // Entry attributes |
| | | // *********************************************** |
| | | ECLIncludeAttributes();replicationServer.clearDb(); |
| | | } |
| | | |
| | | //======================================================= |
| | |
| | | server1.stop(); |
| | | server2.stop(); |
| | | server3.stop(); |
| | | sleep(500); |
| | | debugInfo(tn, "Ending test successfully\n\n"); |
| | | } |
| | | catch(Exception e) |
| | |
| | | // clean |
| | | serverECL.stop(); |
| | | server01.stop(); |
| | | server02.stop(); |
| | | sleep(2000); |
| | | server02.stop(); |
| | | debugInfo(tn, "Ending test successfully"); |
| | | } |
| | | catch(Exception e) |
| | |
| | | // Initialize a second test backend o=test2, in addtion to o=test |
| | | // Configure replication on this backend |
| | | // Add the root entry in the backend |
| | | Backend backend2 = initializeTestBackend2(false); |
| | | Backend backend2 = initializeTestBackend(false, TEST_ROOT_DN_STRING2, |
| | | TEST_BACKEND_ID2); |
| | | DN baseDn2 = DN.decode(TEST_ROOT_DN_STRING2); |
| | | SortedSet<String> replServers = new TreeSet<String>(); |
| | | replServers.add("localhost:"+replicationServerPort); |
| | |
| | | assertEquals(searchOp.getResultCode(), ResultCode.SUCCESS, |
| | | searchOp.getErrorMessage().toString() + searchOp.getAdditionalLogMessage()); |
| | | LinkedList<SearchResultEntry> entries = searchOp.getSearchEntries(); |
| | | assertEquals(entries.size(),2, "Entries number returned by search"); |
| | | assertTrue(entries != null); |
| | | if (entries != null) |
| | | { |
| | | int i = 0; |
| | | for (SearchResultEntry resultEntry : entries) |
| | | { |
| | | i++; |
| | | // Expect |
| | | debugInfo(tn, "Entry returned when test2 is public =" + |
| | | resultEntry.toLDIFString()); |
| | | |
| | | // Test entry attributes |
| | | //if (i==2) |
| | | //{ |
| | | // checkPossibleValues(resultEntry,"targetobjectclass","top","organization"); |
| | | //} |
| | | } |
| | | assertEquals(entries.size(),2, "Entries number returned by search"); |
| | | |
| | | } |
| | | // |
| | | // Set the backend private and do again a search on ECL that should |
| | | // now not return the entry |
| | |
| | | try |
| | | { |
| | | // Initialize a second test backend |
| | | Backend backend2 = initializeTestBackend2(true); |
| | | Backend backend2 = initializeTestBackend(true, |
| | | TEST_ROOT_DN_STRING2, TEST_BACKEND_ID2); |
| | | |
| | | // |
| | | LDIFWriter ldifWriter = getLDIFWriter(); |
| | |
| | | } |
| | | } |
| | | |
| | | private static String getAttributeValue(Entry entry, String attrName) |
| | | { |
| | | AttributeValue av = null; |
| | | try |
| | | { |
| | | List<Attribute> attrs = entry.getAttribute(attrName); |
| | | Attribute a = attrs.iterator().next(); |
| | | av = a.iterator().next(); |
| | | return av.toString(); |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private static void checkPossibleValues(Entry entry, String attrName, |
| | | String expectedValue1, String expectedValue2) |
| | | { |
| | |
| | | } |
| | | } |
| | | |
| | | private static void checkValues(Entry entry, String attrName, |
| | | Set<String> expectedValues) |
| | | { |
| | | AttributeValue av = null; |
| | | int i=0; |
| | | try |
| | | { |
| | | List<Attribute> attrs = entry.getAttribute(attrName); |
| | | Attribute a; |
| | | Iterator<Attribute> iat = attrs.iterator(); |
| | | while ((a=iat.next())!=null) |
| | | { |
| | | Iterator<AttributeValue> iatv = a.iterator(); |
| | | while ((av = iatv.next())!=null) |
| | | { |
| | | String encodedValue = av.toString(); |
| | | assertTrue( |
| | | expectedValues.contains(encodedValue), |
| | | "In entry " + entry + " attr <" + attrName + "> equals " + |
| | | av + " instead of one of the expected values " + expectedValues); |
| | | i++; |
| | | } |
| | | } |
| | | } |
| | | catch(NoSuchElementException e) |
| | | { |
| | | assertTrue(i==expectedValues.size()); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Test persistent search |
| | | */ |
| | |
| | | */ |
| | | private void debugInfo(String tn, String s) |
| | | { |
| | | //if (debugEnabled()) |
| | | if (debugEnabled()) |
| | | { |
| | | logError(Message.raw(Category.SYNC, Severity.NOTICE, |
| | | "** TEST " + tn + " ** " + s)); |
| | | //TRACER.debugInfo("** TEST " + tn + " ** " + s); |
| | | // logError(Message.raw(Category.SYNC, Severity.NOTICE, |
| | | // "** TEST " + tn + " ** " + s)); |
| | | TRACER.debugInfo("** TEST " + tn + " ** " + s); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Utility - create a second backend in order to test ECL with 2 suffixes. |
| | | */ |
| | | private static Backend initializeTestBackend2(boolean createBaseEntry) |
| | | private static Backend initializeTestBackend( |
| | | boolean createBaseEntry, |
| | | String rootDN, |
| | | String backendId) |
| | | throws IOException, InitializationException, ConfigException, |
| | | DirectoryException |
| | | { |
| | | |
| | | DN baseDN = DN.decode(TEST_ROOT_DN_STRING2); |
| | | DN baseDN = DN.decode(rootDN); |
| | | |
| | | // Retrieve backend. Warning: it is important to perform this each time, |
| | | // because a test may have disabled then enabled the backend (i.e a test |
| | |
| | | // to memory backend must be invalidated. So to prevent this problem, we |
| | | // retrieve the memory backend reference each time before cleaning it. |
| | | MemoryBackend memoryBackend = |
| | | (MemoryBackend)DirectoryServer.getBackend(TEST_BACKEND_ID2); |
| | | (MemoryBackend)DirectoryServer.getBackend(backendId); |
| | | |
| | | if (memoryBackend == null) |
| | | { |
| | | memoryBackend = new MemoryBackend(); |
| | | memoryBackend.setBackendID(TEST_BACKEND_ID2); |
| | | memoryBackend.setBackendID(backendId); |
| | | memoryBackend.setBaseDNs(new DN[] {baseDN}); |
| | | memoryBackend.initializeBackend(); |
| | | DirectoryServer.registerBackend(memoryBackend); |
| | |
| | | try |
| | | { |
| | | // Initialize a second test backend |
| | | Backend backend2 = initializeTestBackend2(true); |
| | | Backend backend2 = initializeTestBackend(true, TEST_ROOT_DN_STRING2, |
| | | TEST_BACKEND_ID2); |
| | | |
| | | // -- |
| | | ReplicationBroker s1test = openReplicationSession( |
| | |
| | | } |
| | | } |
| | | assertEquals(searchOp.getSearchEntries().size(), 4); |
| | | |
| | | |
| | | } |
| | | catch(Exception e) |
| | | { |
| | |
| | | debugInfo(tn, "Ending test with success"); |
| | | } |
| | | |
| | | /** |
| | | * Test ECl entry attributes, and there configuration. |
| | | * |
| | | */ |
| | | private void ECLIncludeAttributes() |
| | | { |
| | | String tn = "ECLIncludeAttributes"; |
| | | debugInfo(tn, "Starting test\n\n"); |
| | | try |
| | | { |
| | | // Initialize a second test backend o=test2, in addtion to o=test |
| | | // Configure replication on this backend |
| | | // Add the root entry in the backend |
| | | Backend backend2 = initializeTestBackend(false, |
| | | TEST_ROOT_DN_STRING2, TEST_BACKEND_ID2); |
| | | DN baseDn2 = DN.decode(TEST_ROOT_DN_STRING2); |
| | | SortedSet<String> replServers = new TreeSet<String>(); |
| | | replServers.add("localhost:"+replicationServerPort); |
| | | DomainFakeCfg domainConf = |
| | | new DomainFakeCfg(baseDn2, (short) 1702, replServers); |
| | | SortedSet<String> includeAttributes = new TreeSet<String>(); |
| | | includeAttributes.add("sn"); |
| | | domainConf.setEclIncludes(includeAttributes); |
| | | LDAPReplicationDomain domain2 = MultimasterReplication.createNewDomain(domainConf); |
| | | SynchronizationProvider replicationPlugin2 = new MultimasterReplication(); |
| | | replicationPlugin2.completeSynchronizationProvider(); |
| | | |
| | | Backend backend3 = initializeTestBackend(false, |
| | | TEST_ROOT_DN_STRING3, TEST_BACKEND_ID3); |
| | | DN baseDn3 = DN.decode(TEST_ROOT_DN_STRING3); |
| | | domainConf = |
| | | new DomainFakeCfg(baseDn3, (short) 1703, replServers); |
| | | includeAttributes = new TreeSet<String>(); |
| | | includeAttributes.add("objectclass"); |
| | | domainConf.setEclIncludes(includeAttributes); |
| | | LDAPReplicationDomain domain3 = MultimasterReplication.createNewDomain(domainConf); |
| | | SynchronizationProvider replicationPlugin3 = new MultimasterReplication(); |
| | | replicationPlugin3.completeSynchronizationProvider(); |
| | | |
| | | domainConf = |
| | | new DomainFakeCfg(baseDn2, (short) 1704, replServers); |
| | | includeAttributes = new TreeSet<String>(); |
| | | includeAttributes.add("cn"); |
| | | domainConf.setEclIncludes(includeAttributes); |
| | | LDAPReplicationDomain domain21 = MultimasterReplication.createNewDomain(domainConf); |
| | | |
| | | Set<String> attrList = new HashSet<String>(); |
| | | attrList.add(new String("cn")); |
| | | ReplicationBroker server01 = openReplicationSession( |
| | | DN.decode(TEST_ROOT_DN_STRING2), (short) 1206, |
| | | 100, replicationServerPort, |
| | | 1000, true, -1 , domain21); |
| | | |
| | | sleep(1000); |
| | | |
| | | Entry e2 = createEntry(baseDn2); |
| | | addEntry(e2); |
| | | |
| | | Entry e3 = createEntry(baseDn3); |
| | | addEntry(e3); |
| | | |
| | | String lentry = new String( |
| | | "dn: cn=Fiona Jensen," + TEST_ROOT_DN_STRING2 + "\n" |
| | | + "objectclass: top\n" |
| | | + "objectclass: person\n" |
| | | + "objectclass: organizationalPerson\n" |
| | | + "objectclass: inetOrgPerson\n" |
| | | + "cn: Fiona Jensen\n" |
| | | + "sn: Jensen\n" |
| | | + "uid: fiona\n" |
| | | + "telephonenumber: 12121212"); |
| | | |
| | | Entry uentry1 = TestCaseUtils.entryFromLdifString(lentry); |
| | | addEntry(uentry1); |
| | | |
| | | lentry = new String( |
| | | "dn: cn=Robert Hue," + TEST_ROOT_DN_STRING3 + "\n" |
| | | + "objectclass: top\n" |
| | | + "objectclass: person\n" |
| | | + "objectclass: organizationalPerson\n" |
| | | + "objectclass: inetOrgPerson\n" |
| | | + "cn: Robert Hue\n" |
| | | + "sn: Robby\n" |
| | | + "uid: robert\n" |
| | | + "telephonenumber: 131313"); |
| | | Entry uentry2 = TestCaseUtils.entryFromLdifString(lentry); |
| | | addEntry(uentry2); |
| | | |
| | | AttributeBuilder builder = new AttributeBuilder("sn"); |
| | | builder.add("newsn"); |
| | | Modification mod = |
| | | new Modification(ModificationType.REPLACE, builder.toAttribute()); |
| | | List<Modification> mods = new ArrayList<Modification>(); |
| | | mods.add(mod); |
| | | |
| | | ModifyOperationBasis modOpBasis = |
| | | new ModifyOperationBasis(connection, 1, 1, null, uentry1.getDN(), mods); |
| | | modOpBasis.run(); |
| | | |
| | | builder = new AttributeBuilder("telephonenumber"); |
| | | builder.add("555555"); |
| | | mod = |
| | | new Modification(ModificationType.REPLACE, builder.toAttribute()); |
| | | mods = new ArrayList<Modification>(); |
| | | mods.add(mod); |
| | | |
| | | modOpBasis = |
| | | new ModifyOperationBasis(connection, 1, 1, null, uentry2.getDN(), mods); |
| | | modOpBasis.run(); |
| | | |
| | | ModifyDNOperationBasis modDNOp = new ModifyDNOperationBasis(connection, |
| | | InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), |
| | | null, |
| | | DN.decode("cn=Robert Hue," + TEST_ROOT_DN_STRING3), |
| | | RDN.decode("cn=Robert Hue2"), true, |
| | | DN.decode(TEST_ROOT_DN_STRING3)); |
| | | modDNOp.run(); |
| | | assertEquals(modDNOp.getResultCode(), ResultCode.SUCCESS, |
| | | modDNOp.getErrorMessage().toString() + modDNOp.getAdditionalLogMessage()); |
| | | |
| | | DeleteOperationBasis delOp = new DeleteOperationBasis(connection, |
| | | InternalClientConnection.nextOperationID(), |
| | | InternalClientConnection.nextMessageID(), null, |
| | | DN.decode("cn=Robert Hue2," + TEST_ROOT_DN_STRING3)); |
| | | delOp.run(); |
| | | assertEquals(delOp.getResultCode(), ResultCode.SUCCESS, |
| | | delOp.getErrorMessage().toString() + delOp.getAdditionalLogMessage()); |
| | | |
| | | sleep(400); |
| | | |
| | | // Search on ECL from start on all suffixes |
| | | String cookie = ""; |
| | | ExternalChangelogRequestControl control = |
| | | new ExternalChangelogRequestControl(true, |
| | | new MultiDomainServerState(cookie)); |
| | | ArrayList<Control> controls = new ArrayList<Control>(0); |
| | | controls.add(control); |
| | | LinkedHashSet<String> attributes = new LinkedHashSet<String>(); |
| | | attributes.add("+"); |
| | | attributes.add("*"); |
| | | |
| | | |
| | | debugInfo(tn, "Search with cookie=" + cookie); |
| | | InternalSearchOperation searchOp = connection.processSearch( |
| | | ByteString.valueOf("cn=changelog"), |
| | | SearchScope.WHOLE_SUBTREE, |
| | | DereferencePolicy.NEVER_DEREF_ALIASES, |
| | | 0, // Size limit |
| | | 0, // Time limit |
| | | false, // Types only |
| | | LDAPFilter.decode("(targetDN=*)"), |
| | | attributes, |
| | | controls, |
| | | null); |
| | | |
| | | sleep(500); |
| | | |
| | | // Expect SUCCESS and root entry returned |
| | | assertEquals(searchOp.getResultCode(), ResultCode.SUCCESS, |
| | | searchOp.getErrorMessage().toString() + searchOp.getAdditionalLogMessage()); |
| | | LinkedList<SearchResultEntry> entries = searchOp.getSearchEntries(); |
| | | |
| | | |
| | | assertEquals(entries.size(),8, "Entries number returned by search"); |
| | | assertTrue(entries != null); |
| | | |
| | | if (entries != null) |
| | | { |
| | | for (SearchResultEntry resultEntry : entries) |
| | | { |
| | | // Expect |
| | | debugInfo(tn, "Entry returned =" + resultEntry.toLDIFString()); |
| | | |
| | | String targetdn = getAttributeValue(resultEntry, "targetdn"); |
| | | if ((targetdn.endsWith("cn=robert hue,o=test3")) |
| | | ||(targetdn.endsWith("cn=robert hue2,o=test3"))) |
| | | { |
| | | HashSet<String> eoc = new HashSet<String>(); |
| | | eoc.add("person");eoc.add("inetOrgPerson");eoc.add("organizationalPerson");eoc.add("top"); |
| | | checkValues(resultEntry,"targetobjectclass",eoc); |
| | | } |
| | | if (targetdn.endsWith("cn=fiona jensen,o=test2")) |
| | | { |
| | | checkValue(resultEntry,"targetsn","jensen"); |
| | | checkValue(resultEntry,"targetcn","Fiona Jensen"); |
| | | } |
| | | } |
| | | } |
| | | server01.stop(); |
| | | |
| | | // Cleaning |
| | | if (domain2 != null) |
| | | MultimasterReplication.deleteDomain(baseDn2); |
| | | if (replicationPlugin2 != null) |
| | | DirectoryServer.deregisterSynchronizationProvider(replicationPlugin2); |
| | | removeTestBackend2(backend2); |
| | | |
| | | if (domain3 != null) |
| | | MultimasterReplication.deleteDomain(baseDn3); |
| | | if (replicationPlugin3 != null) |
| | | DirectoryServer.deregisterSynchronizationProvider(replicationPlugin3); |
| | | removeTestBackend2(backend3); |
| | | |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | fail("Ending "+tn+" test with exception:\n" |
| | | + stackTraceToSingleLineString(e)); |
| | | } |
| | | finally |
| | | { |
| | | |
| | | } |
| | | debugInfo(tn, "Ending test with success"); |
| | | } |
| | | } |
| | |
| | | */ |
| | | package org.opends.server.replication; |
| | | |
| | | import java.io.File; |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | | import static org.opends.server.config.ConfigConstants.ATTR_TASK_COMPLETION_TIME; |
| | | import static org.opends.server.config.ConfigConstants.ATTR_TASK_LOG_MESSAGES; |
| | | import static org.opends.server.config.ConfigConstants.ATTR_TASK_STATE; |
| | | import static org.opends.server.loggers.ErrorLogger.logError; |
| | | import static org.opends.server.loggers.debug.DebugLogger.getTracer; |
| | | import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString; |
| | |
| | | import static org.testng.Assert.assertTrue; |
| | | import static org.testng.Assert.fail; |
| | | |
| | | import java.io.File; |
| | | import java.net.SocketException; |
| | | import java.util.ArrayList; |
| | | import java.util.LinkedList; |
| | |
| | | import org.opends.messages.MessageBuilder; |
| | | import org.opends.messages.Severity; |
| | | import org.opends.server.DirectoryServerTestCase; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.backends.task.TaskState; |
| | | import org.opends.server.config.ConfigException; |
| | | import org.opends.server.core.AddOperation; |
| | |
| | | import org.opends.server.protocols.internal.InternalClientConnection; |
| | | import org.opends.server.protocols.internal.InternalSearchOperation; |
| | | import org.opends.server.protocols.ldap.LDAPFilter; |
| | | import org.opends.server.replication.service.ReplicationBroker; |
| | | import org.opends.server.replication.common.ServerState; |
| | | import org.opends.server.replication.plugin.PersistentServerState; |
| | | import org.opends.server.replication.plugin.LDAPReplicationDomain; |
| | | import org.opends.server.replication.plugin.MultimasterReplication; |
| | | import org.opends.server.replication.plugin.PersistentServerState; |
| | | import org.opends.server.replication.protocol.ErrorMsg; |
| | | import org.opends.server.replication.protocol.ReplSessionSecurity; |
| | | import org.opends.server.replication.protocol.ReplicationMsg; |
| | | import org.opends.server.replication.service.ReplicationBroker; |
| | | import org.opends.server.replication.service.ReplicationDomain; |
| | | import org.opends.server.schema.DirectoryStringSyntax; |
| | | import org.opends.server.schema.IntegerSyntax; |
| | | import org.opends.server.types.*; |
| | | import org.opends.server.types.Attribute; |
| | | import org.opends.server.types.AttributeType; |
| | | import org.opends.server.types.AttributeValue; |
| | | import org.opends.server.types.AttributeValues; |
| | | import org.opends.server.types.Attributes; |
| | | import org.opends.server.types.ByteString; |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.Entry; |
| | | import org.opends.server.types.LockManager; |
| | | import org.opends.server.types.Modification; |
| | | import org.opends.server.types.ModificationType; |
| | | import org.opends.server.types.ResultCode; |
| | | import org.opends.server.types.SearchFilter; |
| | | import org.opends.server.types.SearchResultEntry; |
| | | import org.opends.server.types.SearchScope; |
| | | import org.testng.annotations.AfterClass; |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.Test; |
| | | import org.opends.server.TestCaseUtils; |
| | | import org.opends.server.replication.plugin.MultimasterReplication; |
| | | |
| | | /** |
| | | * An abstract class that all Replication unit test should extend. |
| | |
| | | long generationId) |
| | | throws Exception, SocketException |
| | | { |
| | | return openReplicationSession(baseDn, serverId, window_size, |
| | | port, timeout, emptyOldChanges, generationId, null); |
| | | } |
| | | |
| | | /** |
| | | * Open a replicationServer session to the local ReplicationServer |
| | | * providing the generationId. |
| | | */ |
| | | protected ReplicationBroker openReplicationSession( |
| | | final DN baseDn, short serverId, int window_size, |
| | | int port, int timeout, boolean emptyOldChanges, |
| | | long generationId, ReplicationDomain replicationDomain) |
| | | throws Exception, SocketException |
| | | { |
| | | ServerState state = new ServerState(); |
| | | |
| | | if (emptyOldChanges) |
| | | new PersistentServerState(baseDn, serverId, new ServerState()); |
| | | |
| | | ReplicationBroker broker = new ReplicationBroker(null, |
| | | ReplicationBroker broker = new ReplicationBroker(replicationDomain, |
| | | state, baseDn.toNormalizedString(), serverId, window_size, |
| | | generationId, 100000, getReplSessionSecurity(), (byte)1, 500); |
| | | ArrayList<String> servers = new ArrayList<String>(1); |
| | |
| | | final DN baseDn = DN.decode("ou=People," + TEST_ROOT_DN_STRING); |
| | | |
| | | ReplicationBroker broker = |
| | | openReplicationSession(baseDn, (short) 27, 100, replServerPort, 1000, true); |
| | | openReplicationSession(baseDn, (short) 27, 100, replServerPort, 2000, true); |
| | | try { |
| | | ChangeNumberGenerator gen = new ChangeNumberGenerator((short) 27, 0); |
| | | |
| | |
| | | */ |
| | | package org.opends.server.replication.plugin; |
| | | |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.SortedSet; |
| | | |
| | | import java.util.TreeSet; |
| | | |
| | | import org.opends.server.admin.Configuration; |
| | | import org.opends.server.admin.server.ConfigurationChangeListener; |
| | | import org.opends.server.admin.server.ServerManagedObject; |
| | |
| | | private SortedSet<String> fractionalExcludes = new TreeSet<String>(); |
| | | private SortedSet<String> fractionalIncludes = new TreeSet<String>(); |
| | | |
| | | private SortedSet<String> eclIncludes = new TreeSet<String>(); |
| | | |
| | | /** |
| | | * Creates a new Domain with the provided information |
| | | * (assured mode disabled, default group id) |
| | |
| | | { |
| | | return true; |
| | | } |
| | | |
| | | public void setEclIncludes(SortedSet<String> attrs) |
| | | { |
| | | this.eclIncludes = attrs; |
| | | } |
| | | |
| | | public SortedSet<String> getEclInclude() |
| | | { |
| | | return this.eclIncludes; |
| | | } |
| | | } |
| | |
| | | */ |
| | | package org.opends.server.replication.plugin; |
| | | |
| | | import static org.opends.server.TestCaseUtils.TEST_ROOT_DN_STRING; |
| | | import static org.opends.server.loggers.ErrorLogger.logError; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | | import static org.opends.server.loggers.debug.DebugLogger.getTracer; |
| | | import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString; |
| | | import static org.testng.Assert.assertEquals; |
| | | import static org.testng.Assert.assertFalse; |
| | | import static org.testng.Assert.assertNotNull; |
| | | import static org.testng.Assert.fail; |
| | | |
| | | import java.io.IOException; |
| | | import java.net.ServerSocket; |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.SortedSet; |
| | | import java.util.TreeSet; |
| | | |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | | import static org.opends.server.loggers.ErrorLogger.logError; |
| | | import static org.opends.server.loggers.debug.DebugLogger.getTracer; |
| | | import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString; |
| | | |
| | | import org.opends.messages.Category; |
| | | import org.opends.messages.Message; |
| | | import org.opends.messages.Severity; |
| | |
| | | import org.opends.server.types.DN; |
| | | import org.opends.server.types.DirectoryException; |
| | | import org.testng.annotations.Test; |
| | | import static org.testng.Assert.*; |
| | | import static org.opends.server.TestCaseUtils.*; |
| | | |
| | | /** |
| | | * Some tests to know if at any time the view DSs and RSs have of the current |
| | |
| | | AssuredType assuredType = null; |
| | | int assuredSdLevel = -100; |
| | | SortedSet<String> refUrls = null; |
| | | SortedSet<String> attrs = null; |
| | | |
| | | switch (dsId) |
| | | { |
| | |
| | | } |
| | | |
| | | return new DSInfo(dsId, rsId, TEST_DN_WITH_ROOT_ENTRY_GENID, status, assuredFlag, assMode, |
| | | (byte)assuredSdLevel, groupId, urls); |
| | | (byte)assuredSdLevel, groupId, urls, attrs); |
| | | } |
| | | |
| | | /** |
| | |
| | | byte safeDataLevel = rd.getAssuredSdLevel(); |
| | | byte groupId = rd.getGroupId(); |
| | | List<String> refUrls = rd.getRefUrls(); |
| | | Set<String> eclInclude = rd.getEclInclude(); |
| | | DSInfo dsInfo = new DSInfo(dsId, rsId, TEST_DN_WITH_ROOT_ENTRY_GENID, status, assuredFlag, assuredMode, |
| | | safeDataLevel, groupId, refUrls); |
| | | safeDataLevel, groupId, refUrls, eclInclude); |
| | | dsList.add(dsInfo); |
| | | |
| | | TopoView dsTopoView = new TopoView(dsList, rd.getRsList()); |
| | |
| | | import org.opends.server.types.ModificationType; |
| | | import org.opends.server.types.ObjectClass; |
| | | import org.opends.server.types.Operation; |
| | | import org.opends.server.types.RawAttribute; |
| | | import org.opends.server.util.TimeThread; |
| | | import org.testng.annotations.AfterClass; |
| | | import org.testng.annotations.BeforeClass; |
| | |
| | | */ |
| | | public class ProtocolCompatibilityTest extends ReplicationTestCase { |
| | | |
| | | short REPLICATION_PROTOCOL_VLAST = ProtocolVersion.REPLICATION_PROTOCOL_V3; |
| | | short REPLICATION_PROTOCOL_VLAST = ProtocolVersion.REPLICATION_PROTOCOL_V4; |
| | | /** |
| | | * Set up the environment for performing the tests in this Class. |
| | | * |
| | |
| | | } |
| | | |
| | | @DataProvider(name = "createAddData") |
| | | public Object[][] createAddData() { |
| | | public Object[][] createAddData() |
| | | { |
| | | // Entry attributes |
| | | Attribute eattr1 = Attributes.create("description", "eav description"); |
| | | Attribute eattr2 = Attributes.create("namingcontexts", "eav naming contexts"); |
| | | List<Attribute> entryAttrList = new ArrayList<Attribute>(); |
| | | entryAttrList.add(eattr1); |
| | | entryAttrList.add(eattr2); |
| | | |
| | | return new Object[][] { |
| | | {"dc=example,dc=com", false, AssuredMode.SAFE_DATA_MODE, (byte)0}, |
| | | {"o=test", true, AssuredMode.SAFE_READ_MODE, (byte)1}, |
| | | {"o=group,dc=example,dc=com", true, AssuredMode.SAFE_READ_MODE, (byte)3}}; |
| | | {"dc=example,dc=com", false, AssuredMode.SAFE_DATA_MODE, (byte)0, null}, |
| | | {"o=test", true, AssuredMode.SAFE_READ_MODE, (byte)1, entryAttrList}, |
| | | {"o=group,dc=example,dc=com", true, AssuredMode.SAFE_READ_MODE, (byte)3, entryAttrList}}; |
| | | } |
| | | |
| | | @Test(dataProvider = "createAddData") |
| | | public void addMsgTestVLASTV2(String rawDN, boolean isAssured, AssuredMode assuredMode, |
| | | byte safeDataLevel) |
| | | byte safeDataLevel, List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | // TODO: addMsgTest as soon as V3 will have any incompatibility with V2 |
| | |
| | | |
| | | @Test(dataProvider = "createAddData") |
| | | public void addMsgTestVLASTV1(String rawDN, boolean isAssured, AssuredMode assuredMode, |
| | | byte safeDataLevel) |
| | | throws Exception |
| | | byte safeDataLevel, List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | // Create VLAST message |
| | | Attribute objectClass = Attributes.create(DirectoryServer |
| | |
| | | msg.setAssured(isAssured); |
| | | msg.setAssuredMode(assuredMode); |
| | | msg.setSafeDataLevel(safeDataLevel); |
| | | // Set ECL entry attributes |
| | | if (entryAttrList != null) |
| | | { |
| | | msg.setEclIncludes(entryAttrList); |
| | | } |
| | | |
| | | // Check version of message |
| | | assertEquals(msg.getVersion(), REPLICATION_PROTOCOL_VLAST); |
| | |
| | | assertEquals(newMsg.isAssured(), msg.isAssured()); |
| | | assertEquals(newMsg.getParentUid(), msg.getParentUid()); |
| | | |
| | | // Create an add operation from each message to compare attributes (kept encoded in messages) |
| | | // Create an add operation from each message to compare attributes (kept encoded in messages) |
| | | Operation op = msg.createOperation(connection, rawDN); |
| | | Operation generatedOperation = newMsg.createOperation(connection, rawDN); |
| | | |
| | |
| | | // Check default value for only VLAST fields |
| | | assertEquals(newMsg.getAssuredMode(), AssuredMode.SAFE_DATA_MODE); |
| | | assertEquals(newMsg.getSafeDataLevel(), (byte)1); |
| | | assertEquals(newMsg.getEclIncludes().size(), 0); |
| | | |
| | | // Set again only VLAST fields |
| | | newMsg.setAssuredMode(assuredMode); |
| | | newMsg.setSafeDataLevel(safeDataLevel); |
| | | if (entryAttrList != null) |
| | | { |
| | | newMsg.setEclIncludes(entryAttrList); |
| | | } |
| | | |
| | | // Serialize in VLAST msg |
| | | AddMsg vlastMsg = (AddMsg)ReplicationMsg.generateMsg( |
| | |
| | | assertEquals(msg.getAssuredMode(), vlastMsg.getAssuredMode()); |
| | | assertEquals(msg.getSafeDataLevel(), vlastMsg.getSafeDataLevel()); |
| | | |
| | | // Get ECL entry attributes |
| | | ArrayList<RawAttribute> genAttrList = vlastMsg.getEclIncludes(); |
| | | if (entryAttrList==null) |
| | | assertTrue(genAttrList.size()==0); |
| | | else |
| | | { |
| | | assertTrue(genAttrList.size()==entryAttrList.size()); |
| | | int i=0; |
| | | for (Attribute eattr : entryAttrList) |
| | | { |
| | | assertTrue(eattr.getName().equalsIgnoreCase(genAttrList.get(i).toAttribute().getName())); |
| | | assertTrue(eattr.toString().equalsIgnoreCase(genAttrList.get(i).toAttribute().toString()), |
| | | "Comparing: " + eattr.toString() + " and " + genAttrList.get(i).toAttribute().toString()); |
| | | i++; |
| | | } |
| | | } |
| | | |
| | | // Create an add operation from each message to compare attributes (kept encoded in messages) |
| | | op = msg.createOperation(connection, rawDN); |
| | | generatedOperation = vlastMsg.createOperation(connection, rawDN); |
| | |
| | | * Build some data for the DeleteMsg test below. |
| | | */ |
| | | @DataProvider(name = "createDeleteData") |
| | | public Object[][] createDeleteData() { |
| | | public Object[][] createDeleteData() |
| | | { |
| | | // Entry attributes |
| | | Attribute eattr1 = Attributes.create("description", "eav description"); |
| | | Attribute eattr2 = Attributes.create("namingcontexts", "eav naming contexts"); |
| | | List<Attribute> entryAttrList = new ArrayList<Attribute>(); |
| | | entryAttrList.add(eattr1); |
| | | entryAttrList.add(eattr2); |
| | | |
| | | return new Object[][] { |
| | | {"dc=example,dc=com", false, AssuredMode.SAFE_DATA_MODE, (byte)0}, |
| | | {"dc=delete,dc=an,dc=entry,dc=with,dc=a,dc=long dn", true, AssuredMode.SAFE_READ_MODE, (byte)1}, |
| | | {"o=group,dc=example,dc=com", true, AssuredMode.SAFE_READ_MODE, (byte)3}}; |
| | | {"dc=example,dc=com", false, AssuredMode.SAFE_DATA_MODE, (byte)0, null}, |
| | | {"dc=delete,dc=an,dc=entry,dc=with,dc=a,dc=long dn", true, AssuredMode.SAFE_READ_MODE, (byte)1, entryAttrList}, |
| | | {"o=group,dc=example,dc=com", true, AssuredMode.SAFE_READ_MODE, (byte)3, entryAttrList}}; |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Test(dataProvider = "createDeleteData") |
| | | public void deleteMsgTestVLASTV2(String rawDN, boolean isAssured, AssuredMode assuredMode, |
| | | byte safeDataLevel) |
| | | byte safeDataLevel, List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | // TODO: deleteMsgTestVLASTV2 as soon as V3 will have any incompatibility with V2 |
| | |
| | | */ |
| | | @Test(dataProvider = "createDeleteData") |
| | | public void deleteMsgTestVLASTV1(String rawDN, boolean isAssured, AssuredMode assuredMode, |
| | | byte safeDataLevel) |
| | | throws Exception |
| | | byte safeDataLevel, List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | ChangeNumber cn = new ChangeNumber(TimeThread.getTime(), |
| | | (short) 123, (short) 45); |
| | |
| | | msg.setAssuredMode(assuredMode); |
| | | msg.setSafeDataLevel(safeDataLevel); |
| | | |
| | | // Set ECL entry attributes |
| | | if (entryAttrList != null) |
| | | { |
| | | msg.setEclIncludes(entryAttrList); |
| | | } |
| | | |
| | | // Check version of message |
| | | assertEquals(msg.getVersion(), REPLICATION_PROTOCOL_VLAST); |
| | | |
| | |
| | | // Check default value for only VLAST fields |
| | | assertEquals(newMsg.getAssuredMode(), AssuredMode.SAFE_DATA_MODE); |
| | | assertEquals(newMsg.getSafeDataLevel(), (byte)1); |
| | | assertEquals(newMsg.getEclIncludes().size(), 0); |
| | | |
| | | // Set again only VLAST fields |
| | | newMsg.setAssuredMode(assuredMode); |
| | | newMsg.setSafeDataLevel(safeDataLevel); |
| | | // Set ECL entry attributes |
| | | if (entryAttrList != null) |
| | | { |
| | | newMsg.setEclIncludes(entryAttrList); |
| | | } |
| | | |
| | | // Serialize in VLAST msg |
| | | DeleteMsg vlastMsg = (DeleteMsg)ReplicationMsg.generateMsg( |
| | |
| | | // Check original version of message |
| | | assertEquals(vlastMsg.getVersion(), REPLICATION_PROTOCOL_VLAST); |
| | | |
| | | // Check we retrieve original V2 message (V2 fields) |
| | | // Check we retrieve original VLAST message (VLAST fields) |
| | | assertEquals(msg.getUniqueId(), vlastMsg.getUniqueId()); |
| | | assertEquals(msg.getDn(), vlastMsg.getDn()); |
| | | assertEquals(msg.getChangeNumber(), vlastMsg.getChangeNumber()); |
| | | assertEquals(msg.isAssured(), vlastMsg.isAssured()); |
| | | assertEquals(msg.getAssuredMode(), vlastMsg.getAssuredMode()); |
| | | assertEquals(msg.getSafeDataLevel(), vlastMsg.getSafeDataLevel()); |
| | | |
| | | // Get ECL entry attributes |
| | | ArrayList<RawAttribute> genAttrList = vlastMsg.getEclIncludes(); |
| | | if (entryAttrList==null) |
| | | assertTrue(genAttrList.size()==0); |
| | | else |
| | | { |
| | | assertTrue(genAttrList.size()==entryAttrList.size()); |
| | | int i=0; |
| | | for (Attribute attr : entryAttrList) |
| | | { |
| | | assertTrue(attr.getName().equalsIgnoreCase(genAttrList.get(i).toAttribute().getName())); |
| | | assertTrue(attr.toString().equalsIgnoreCase(genAttrList.get(i).toAttribute().toString()), |
| | | "Comparing: " + attr.toString() + " and " + genAttrList.get(i).toAttribute().toString()); |
| | | i++; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | List<Modification> mods5 = new ArrayList<Modification>(); |
| | | mods5.add(mod5); |
| | | |
| | | // Entry attributes |
| | | Attribute eattr1 = Attributes.create("description", "eav description"); |
| | | Attribute eattr2 = Attributes.create("namingcontexts", "eav naming contexts"); |
| | | List<Attribute> entryAttrList = new ArrayList<Attribute>(); |
| | | entryAttrList.add(eattr1); |
| | | entryAttrList.add(eattr2); |
| | | |
| | | return new Object[][] { |
| | | { cn1, "dc=test", mods1, false, AssuredMode.SAFE_DATA_MODE, (byte)0}, |
| | | { cn2, "dc=cn2", mods1, true, AssuredMode.SAFE_READ_MODE, (byte)1}, |
| | | { cn1, "dc=test", mods1, false, AssuredMode.SAFE_DATA_MODE, (byte)0, null}, |
| | | { cn2, "dc=cn2", mods1, true, AssuredMode.SAFE_READ_MODE, (byte)1, entryAttrList}, |
| | | { cn2, "dc=test with a much longer dn in case this would " |
| | | + "make a difference", mods1, true, AssuredMode.SAFE_READ_MODE, (byte)3}, |
| | | { cn2, "dc=test, cn=with a, o=more complex, ou=dn", mods1, false, AssuredMode.SAFE_READ_MODE, (byte)5}, |
| | | { cn2, "cn=use\\, backslash", mods1, true, AssuredMode.SAFE_READ_MODE, (byte)3}, |
| | | { cn2, "dc=test with several mod", mods2, false, AssuredMode.SAFE_DATA_MODE, (byte)16}, |
| | | { cn2, "dc=test with several values", mods3, false, AssuredMode.SAFE_READ_MODE, (byte)3}, |
| | | { cn2, "dc=test with long mod", mods4, true, AssuredMode.SAFE_READ_MODE, (byte)120}, |
| | | { cn2, "dc=testDsaOperation", mods5, true, AssuredMode.SAFE_DATA_MODE, (byte)99}, |
| | | + "make a difference", mods1, true, AssuredMode.SAFE_READ_MODE, (byte)3, null}, |
| | | { cn2, "dc=test, cn=with a, o=more complex, ou=dn", mods1, false, AssuredMode.SAFE_READ_MODE, (byte)5, entryAttrList}, |
| | | { cn2, "cn=use\\, backslash", mods1, true, AssuredMode.SAFE_READ_MODE, (byte)3, null}, |
| | | { cn2, "dc=test with several mod", mods2, false, AssuredMode.SAFE_DATA_MODE, (byte)16, entryAttrList}, |
| | | { cn2, "dc=test with several values", mods3, false, AssuredMode.SAFE_READ_MODE, (byte)3, null}, |
| | | { cn2, "dc=test with long mod", mods4, true, AssuredMode.SAFE_READ_MODE, (byte)120, entryAttrList}, |
| | | { cn2, "dc=testDsaOperation", mods5, true, AssuredMode.SAFE_DATA_MODE, (byte)99, null}, |
| | | }; |
| | | } |
| | | |
| | |
| | | public void modifyMsgTestVLASTV2(ChangeNumber changeNumber, |
| | | String rawdn, List<Modification> mods, |
| | | boolean isAssured, AssuredMode assuredMode, |
| | | byte safeDataLevel) |
| | | byte safeDataLevel, |
| | | List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | // TODO: modifyMsgTestVLASTV2 as soon as V3 will have any incompatibility with V2 |
| | |
| | | public void modifyMsgTestVLASTV1(ChangeNumber changeNumber, |
| | | String rawdn, List<Modification> mods, |
| | | boolean isAssured, AssuredMode assuredMode, |
| | | byte safeDataLevel) |
| | | byte safeDataLevel, |
| | | List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | // Create VLAST message |
| | | DN dn = DN.decode(rawdn); |
| | | ModifyMsg msg = new ModifyMsg(changeNumber, dn, mods, "fakeuniqueid"); |
| | | ModifyMsg origVlastMsg = new ModifyMsg(changeNumber, dn, mods, "fakeuniqueid"); |
| | | |
| | | msg.setAssured(isAssured); |
| | | msg.setAssuredMode(assuredMode); |
| | | msg.setSafeDataLevel(safeDataLevel); |
| | | origVlastMsg.setAssured(isAssured); |
| | | origVlastMsg.setAssuredMode(assuredMode); |
| | | origVlastMsg.setSafeDataLevel(safeDataLevel); |
| | | // Set ECL entry attributes |
| | | if (entryAttrList != null) |
| | | { |
| | | origVlastMsg.setEclIncludes(entryAttrList); |
| | | } |
| | | |
| | | // Check version of message |
| | | assertEquals(msg.getVersion(), REPLICATION_PROTOCOL_VLAST); |
| | | assertEquals(origVlastMsg.getVersion(), REPLICATION_PROTOCOL_VLAST); |
| | | |
| | | // Serialize in V1 |
| | | byte[] v1MsgBytes = msg.getBytes(ProtocolVersion.REPLICATION_PROTOCOL_V1); |
| | | byte[] v1MsgBytes = origVlastMsg.getBytes(ProtocolVersion.REPLICATION_PROTOCOL_V1); |
| | | |
| | | // Un-serialize V1 message |
| | | ModifyMsg newMsg = (ModifyMsg)ReplicationMsg.generateMsg( |
| | | ModifyMsg newv1Msg = (ModifyMsg)ReplicationMsg.generateMsg( |
| | | v1MsgBytes, ProtocolVersion.REPLICATION_PROTOCOL_V1); |
| | | |
| | | // Check original version of message |
| | | assertEquals(newMsg.getVersion(), ProtocolVersion.REPLICATION_PROTOCOL_V1); |
| | | assertEquals(newv1Msg.getVersion(), ProtocolVersion.REPLICATION_PROTOCOL_V1); |
| | | |
| | | // Check fields common to both versions |
| | | assertEquals(newMsg.getUniqueId(), msg.getUniqueId()); |
| | | assertEquals(newMsg.getDn(), msg.getDn()); |
| | | assertEquals(newMsg.getChangeNumber(), msg.getChangeNumber()); |
| | | assertEquals(newMsg.isAssured(), msg.isAssured()); |
| | | assertEquals(newv1Msg.getUniqueId(), origVlastMsg.getUniqueId()); |
| | | assertEquals(newv1Msg.getDn(), origVlastMsg.getDn()); |
| | | assertEquals(newv1Msg.getChangeNumber(), origVlastMsg.getChangeNumber()); |
| | | assertEquals(newv1Msg.isAssured(), origVlastMsg.isAssured()); |
| | | |
| | | // Create a modify operation from each message to compare mods (kept encoded in messages) |
| | | Operation op = msg.createOperation(connection); |
| | | Operation generatedOperation = newMsg.createOperation(connection); |
| | | // Create a modify operation from each message to compare mods (kept encoded in messages) |
| | | Operation opFromOrigVlast = origVlastMsg.createOperation(connection); |
| | | Operation opFromV1 = newv1Msg.createOperation(connection); |
| | | |
| | | assertEquals(op.getClass(), ModifyOperationBasis.class); |
| | | assertEquals(generatedOperation.getClass(), ModifyOperationBasis.class); |
| | | ModifyOperationBasis modOpBasis = (ModifyOperationBasis) op; |
| | | ModifyOperationBasis genModOpBasis = (ModifyOperationBasis) generatedOperation; |
| | | assertEquals(opFromOrigVlast.getClass(), ModifyOperationBasis.class); |
| | | assertEquals(opFromV1.getClass(), ModifyOperationBasis.class); |
| | | |
| | | ModifyOperationBasis modOpBasisFromOrigVlast = (ModifyOperationBasis) opFromOrigVlast; |
| | | ModifyOperationBasis genModOpBasisFromV1 = (ModifyOperationBasis) opFromV1; |
| | | |
| | | assertEquals(modOpBasis.getRawEntryDN(), genModOpBasis.getRawEntryDN()); |
| | | assertEquals( modOpBasis.getAttachment(SYNCHROCONTEXT), |
| | | genModOpBasis.getAttachment(SYNCHROCONTEXT)); |
| | | assertEquals(modOpBasis.getModifications(), genModOpBasis.getModifications()); |
| | | assertEquals(modOpBasisFromOrigVlast.getRawEntryDN(), genModOpBasisFromV1.getRawEntryDN()); |
| | | assertEquals( modOpBasisFromOrigVlast.getAttachment(SYNCHROCONTEXT), |
| | | genModOpBasisFromV1.getAttachment(SYNCHROCONTEXT)); |
| | | List<Modification> modsvlast = modOpBasisFromOrigVlast.getModifications(); |
| | | List<Modification> modsv1 = genModOpBasisFromV1.getModifications(); |
| | | |
| | | assertEquals(modsvlast, modsv1); |
| | | |
| | | // Check default value for only VLAST fields |
| | | assertEquals(newMsg.getAssuredMode(), AssuredMode.SAFE_DATA_MODE); |
| | | assertEquals(newMsg.getSafeDataLevel(), (byte)1); |
| | | assertEquals(newv1Msg.getAssuredMode(), AssuredMode.SAFE_DATA_MODE); |
| | | assertEquals(newv1Msg.getSafeDataLevel(), (byte)1); |
| | | |
| | | // Set again only VLAST fields |
| | | newMsg.setAssuredMode(assuredMode); |
| | | newMsg.setSafeDataLevel(safeDataLevel); |
| | | |
| | | newv1Msg.setAssuredMode(assuredMode); |
| | | newv1Msg.setSafeDataLevel(safeDataLevel); |
| | | if (entryAttrList != null) |
| | | { |
| | | newv1Msg.setEclIncludes(entryAttrList); |
| | | } |
| | | |
| | | // Serialize in VLAST msg |
| | | ModifyMsg vlastMsg = (ModifyMsg)ReplicationMsg.generateMsg( |
| | | newMsg.getBytes(), ProtocolVersion.REPLICATION_PROTOCOL_V1); |
| | | ModifyMsg generatedVlastMsg = (ModifyMsg)ReplicationMsg.generateMsg( |
| | | newv1Msg.getBytes(), ProtocolVersion.REPLICATION_PROTOCOL_V1); |
| | | |
| | | // Check original version of message |
| | | assertEquals(vlastMsg.getVersion(), REPLICATION_PROTOCOL_VLAST); |
| | | assertEquals(generatedVlastMsg.getVersion(), REPLICATION_PROTOCOL_VLAST); |
| | | |
| | | // Check we retrieve original VLAST message (VLAST fields) |
| | | assertEquals(msg.getUniqueId(), vlastMsg.getUniqueId()); |
| | | assertEquals(msg.getDn(), vlastMsg.getDn()); |
| | | assertEquals(msg.getChangeNumber(), vlastMsg.getChangeNumber()); |
| | | assertEquals(msg.isAssured(), vlastMsg.isAssured()); |
| | | assertEquals(msg.getAssuredMode(), vlastMsg.getAssuredMode()); |
| | | assertEquals(msg.getSafeDataLevel(), vlastMsg.getSafeDataLevel()); |
| | | assertEquals(origVlastMsg.getUniqueId(), generatedVlastMsg.getUniqueId()); |
| | | assertEquals(origVlastMsg.getDn(), generatedVlastMsg.getDn()); |
| | | assertEquals(origVlastMsg.getChangeNumber(), generatedVlastMsg.getChangeNumber()); |
| | | assertEquals(origVlastMsg.isAssured(), generatedVlastMsg.isAssured()); |
| | | assertEquals(origVlastMsg.getAssuredMode(), generatedVlastMsg.getAssuredMode()); |
| | | assertEquals(origVlastMsg.getSafeDataLevel(), generatedVlastMsg.getSafeDataLevel()); |
| | | assertEquals(origVlastMsg.getSafeDataLevel(), generatedVlastMsg.getSafeDataLevel()); |
| | | // Get ECL entry attributes |
| | | ArrayList<RawAttribute> genAttrList = generatedVlastMsg.getEclIncludes(); |
| | | if (entryAttrList==null) |
| | | assertTrue(genAttrList.size()==0); |
| | | else |
| | | { |
| | | assertTrue(genAttrList.size()==entryAttrList.size()); |
| | | int i=0; |
| | | for (Attribute attr : entryAttrList) |
| | | { |
| | | assertTrue(attr.getName().equalsIgnoreCase(genAttrList.get(i).toAttribute().getName())); |
| | | assertTrue(attr.toString().equalsIgnoreCase(genAttrList.get(i).toAttribute().toString()), |
| | | "Comparing: " + attr.toString() + " and " + genAttrList.get(i).toAttribute().toString()); |
| | | i++; |
| | | } |
| | | } |
| | | |
| | | // Create a modify operation from each message to compare mods (kept encoded in messages) |
| | | op = msg.createOperation(connection); |
| | | generatedOperation = vlastMsg.createOperation(connection); |
| | | // Create a modify operation from each message to compare mods (kept encoded in messages) |
| | | opFromOrigVlast = origVlastMsg.createOperation(connection); |
| | | Operation opFromGeneratedVlastMsg = generatedVlastMsg.createOperation(connection); |
| | | |
| | | assertEquals(op.getClass(), ModifyOperationBasis.class); |
| | | assertEquals(generatedOperation.getClass(), ModifyOperationBasis.class); |
| | | modOpBasis = (ModifyOperationBasis) op; |
| | | genModOpBasis = (ModifyOperationBasis) generatedOperation; |
| | | assertEquals(opFromOrigVlast.getClass(), ModifyOperationBasis.class); |
| | | assertEquals(opFromGeneratedVlastMsg.getClass(), ModifyOperationBasis.class); |
| | | |
| | | assertEquals(modOpBasis.getRawEntryDN(), genModOpBasis.getRawEntryDN()); |
| | | assertEquals( modOpBasis.getAttachment(SYNCHROCONTEXT), |
| | | genModOpBasis.getAttachment(SYNCHROCONTEXT)); |
| | | assertEquals(modOpBasis.getModifications(), genModOpBasis.getModifications()); |
| | | modOpBasisFromOrigVlast = (ModifyOperationBasis) opFromOrigVlast; |
| | | ModifyOperationBasis modOpBasisFromGeneratedVlast = (ModifyOperationBasis) opFromGeneratedVlastMsg; |
| | | |
| | | assertEquals(modOpBasisFromOrigVlast.getRawEntryDN(), |
| | | modOpBasisFromGeneratedVlast.getRawEntryDN()); |
| | | assertEquals( modOpBasisFromOrigVlast.getAttachment(SYNCHROCONTEXT), |
| | | modOpBasisFromGeneratedVlast.getAttachment(SYNCHROCONTEXT)); |
| | | assertEquals(modOpBasisFromOrigVlast.getModifications(), |
| | | modOpBasisFromGeneratedVlast.getModifications()); |
| | | } |
| | | |
| | | @DataProvider(name = "createModifyDnData") |
| | |
| | | mods4.add(mod); |
| | | } |
| | | |
| | | // Entry attributes |
| | | Attribute eattr1 = Attributes.create("description", "eav description"); |
| | | Attribute eattr2 = Attributes.create("namingcontexts", "eav naming contexts"); |
| | | List<Attribute> entryAttrList = new ArrayList<Attribute>(); |
| | | entryAttrList.add(eattr1); |
| | | entryAttrList.add(eattr2); |
| | | |
| | | return new Object[][] { |
| | | {"dc=test,dc=com", "dc=new", "11111111-1111-1111-1111-111111111111", "22222222-2222-2222-2222-222222222222", false, "dc=change", mods1, false, AssuredMode.SAFE_DATA_MODE, (byte)0}, |
| | | {"dc=test,dc=com", "dc=new", "33333333-3333-3333-3333-333333333333", "44444444-4444-4444-4444-444444444444", true, "dc=change", mods2, true, AssuredMode.SAFE_READ_MODE, (byte)1}, |
| | | {"dc=test,dc=com", "dc=new", "55555555-5555-5555-5555-555555555555", "66666666-6666-6666-6666-666666666666", false, null, mods3, true, AssuredMode.SAFE_READ_MODE, (byte)3}, |
| | | {"dc=test,dc=com", "dc=new", "11111111-1111-1111-1111-111111111111", "22222222-2222-2222-2222-222222222222", false, "dc=change", mods1, false, AssuredMode.SAFE_DATA_MODE, (byte)0, null}, |
| | | {"dc=test,dc=com", "dc=new", "33333333-3333-3333-3333-333333333333", "44444444-4444-4444-4444-444444444444", true, "dc=change", mods2, true, AssuredMode.SAFE_READ_MODE, (byte)1, entryAttrList}, |
| | | {"dc=test,dc=com", "dc=new", "55555555-5555-5555-5555-555555555555", "66666666-6666-6666-6666-666666666666", false, null, mods3, true, AssuredMode.SAFE_READ_MODE, (byte)3, null}, |
| | | {"dc=delete,dc=an,dc=entry,dc=with,dc=a,dc=long dn", |
| | | "dc=new", "77777777-7777-7777-7777-777777777777", "88888888-8888-8888-8888-888888888888",true, null, mods4, true, AssuredMode.SAFE_DATA_MODE, (byte)99}, |
| | | "dc=new", "77777777-7777-7777-7777-777777777777", "88888888-8888-8888-8888-888888888888",true, null, mods4, true, AssuredMode.SAFE_DATA_MODE, (byte)99, entryAttrList}, |
| | | }; |
| | | } |
| | | |
| | |
| | | public void modifyDnMsgTestVLASTV2(String rawDN, String newRdn, String uid, String newParentUid, |
| | | boolean deleteOldRdn, String newSuperior, |
| | | List<Modification> mods, boolean isAssured, |
| | | AssuredMode assuredMode, byte safeDataLevel) |
| | | AssuredMode assuredMode, byte safeDataLevel, |
| | | List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | // TODO: modifyMsgTestVLASTV2 as soon as V3 will have any incompatibility with V2 |
| | |
| | | public void modifyDnMsgTestVLASTV1(String rawDN, String newRdn, String uid, String newParentUid, |
| | | boolean deleteOldRdn, String newSuperior, |
| | | List<Modification> mods, boolean isAssured, |
| | | AssuredMode assuredMode, byte safeDataLevel) |
| | | AssuredMode assuredMode, byte safeDataLevel, |
| | | List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | // Create VLAST message |
| | |
| | | msg.setAssuredMode(assuredMode); |
| | | msg.setSafeDataLevel(safeDataLevel); |
| | | |
| | | // Set ECL entry attributes |
| | | if (entryAttrList != null) |
| | | { |
| | | msg.setEclIncludes(entryAttrList); |
| | | } |
| | | |
| | | // Check version of message |
| | | assertEquals(msg.getVersion(), REPLICATION_PROTOCOL_VLAST); |
| | | |
| | |
| | | assertEquals(newMsg.getNewSuperiorId(), msg.getNewSuperiorId()); |
| | | assertEquals(newMsg.deleteOldRdn(), msg.deleteOldRdn()); |
| | | |
| | | // Create a modDn operation from each message to compare fields) |
| | | // Create a modDn operation from each message to compare fields) |
| | | Operation op = msg.createOperation(connection); |
| | | Operation generatedOperation = newMsg.createOperation(connection); |
| | | |
| | |
| | | newMsg.setAssuredMode(assuredMode); |
| | | newMsg.setSafeDataLevel(safeDataLevel); |
| | | newMsg.setMods(mods); |
| | | // Set ECL entry attributes |
| | | if (entryAttrList != null) |
| | | { |
| | | newMsg.setEclIncludes(entryAttrList); |
| | | } |
| | | |
| | | // Serialize in VLAST msg |
| | | ModifyDNMsg vlastMsg = (ModifyDNMsg)ReplicationMsg.generateMsg( |
| | |
| | | assertEquals(msg.getNewSuperiorId(), vlastMsg.getNewSuperiorId()); |
| | | assertEquals(msg.deleteOldRdn(), vlastMsg.deleteOldRdn()); |
| | | |
| | | // Create a modDn operation from each message to compare mods (kept encoded in messages) |
| | | // Get ECL entry attributes |
| | | ArrayList<RawAttribute> genAttrList = vlastMsg.getEclIncludes(); |
| | | if (entryAttrList==null) |
| | | assertTrue(genAttrList.size()==0); |
| | | else |
| | | { |
| | | assertTrue(genAttrList.size()==entryAttrList.size()); |
| | | int i=0; |
| | | for (Attribute attr : entryAttrList) |
| | | { |
| | | assertTrue(attr.getName().equalsIgnoreCase(genAttrList.get(i).toAttribute().getName())); |
| | | assertTrue(attr.toString().equalsIgnoreCase(genAttrList.get(i).toAttribute().toString()), |
| | | "Comparing: " + attr.toString() + " and " + genAttrList.get(i).toAttribute().toString()); |
| | | i++; |
| | | } |
| | | } |
| | | |
| | | // Create a modDn operation from each message to compare mods (kept encoded in messages) |
| | | op = msg.createOperation(connection); |
| | | generatedOperation = vlastMsg.createOperation(connection); |
| | | |
| | |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.HashMap; |
| | | import java.util.HashSet; |
| | | import java.util.Iterator; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.util.UUID; |
| | | import java.util.zip.DataFormatException; |
| | | |
| | |
| | | import org.opends.server.core.DeleteOperationBasis; |
| | | import org.opends.server.core.DirectoryServer; |
| | | import org.opends.server.core.ModifyDNOperationBasis; |
| | | import org.opends.server.core.ModifyOperation; |
| | | import org.opends.server.core.ModifyOperationBasis; |
| | | import org.opends.server.protocols.internal.InternalClientConnection; |
| | | import org.opends.server.replication.ReplicationTestCase; |
| | |
| | | import org.opends.server.types.ObjectClass; |
| | | import org.opends.server.types.Operation; |
| | | import org.opends.server.types.RDN; |
| | | import org.opends.server.types.RawAttribute; |
| | | import org.opends.server.util.TimeThread; |
| | | import org.opends.server.workflowelement.localbackend.LocalBackendAddOperation; |
| | | import org.opends.server.workflowelement.localbackend.LocalBackendDeleteOperation; |
| | | import org.opends.server.workflowelement.localbackend.LocalBackendModifyDNOperation; |
| | | import org.opends.server.workflowelement.localbackend.LocalBackendModifyOperation; |
| | | import org.testng.annotations.BeforeClass; |
| | | import org.testng.annotations.DataProvider; |
| | | import org.testng.annotations.Test; |
| | |
| | | List<Modification> mods5 = new ArrayList<Modification>(); |
| | | mods5.add(mod5); |
| | | |
| | | // Entry attributes |
| | | Attribute eattr1 = Attributes.create("description", "eav description"); |
| | | Attribute eattr2 = Attributes.create("namingcontexts", "eav naming contexts"); |
| | | List<Attribute> eclIncludes = new ArrayList<Attribute>(); |
| | | eclIncludes.add(eattr1); |
| | | eclIncludes.add(eattr2); |
| | | |
| | | return new Object[][] { |
| | | { cn1, "dc=test", mods1, false, AssuredMode.SAFE_DATA_MODE, (byte)0}, |
| | | { cn2, "dc=cn2", mods1, true, AssuredMode.SAFE_READ_MODE, (byte)1}, |
| | | { cn1, "dc=test", mods1, false, AssuredMode.SAFE_DATA_MODE, (byte)0, null}, |
| | | { cn2, "dc=cn2", mods1, true, AssuredMode.SAFE_READ_MODE, (byte)1, eclIncludes}, |
| | | { cn2, "dc=test with a much longer dn in case this would " |
| | | + "make a difference", mods1, true, AssuredMode.SAFE_READ_MODE, (byte)3}, |
| | | { cn2, "dc=test, cn=with a, o=more complex, ou=dn", mods1, false, AssuredMode.SAFE_READ_MODE, (byte)5}, |
| | | { cn2, "cn=use\\, backslash", mods1, true, AssuredMode.SAFE_READ_MODE, (byte)3}, |
| | | { cn2, "dc=test with several mod", mods2, false, AssuredMode.SAFE_DATA_MODE, (byte)16}, |
| | | { cn2, "dc=test with several values", mods3, false, AssuredMode.SAFE_READ_MODE, (byte)3}, |
| | | { cn2, "dc=test with long mod", mods4, true, AssuredMode.SAFE_READ_MODE, (byte)120}, |
| | | { cn2, "dc=testDsaOperation", mods5, true, AssuredMode.SAFE_DATA_MODE, (byte)99}, |
| | | + "make a difference", mods1, true, AssuredMode.SAFE_READ_MODE, (byte)3, null}, |
| | | { cn2, "dc=test, cn=with a, o=more complex, ou=dn", mods1, false, AssuredMode.SAFE_READ_MODE, (byte)5, eclIncludes}, |
| | | { cn2, "cn=use\\, backslash", mods1, true, AssuredMode.SAFE_READ_MODE, (byte)3, null}, |
| | | { cn2, "dc=test with several mod", mods2, false, AssuredMode.SAFE_DATA_MODE, (byte)16, eclIncludes}, |
| | | { cn2, "dc=test with several values", mods3, false, AssuredMode.SAFE_READ_MODE, (byte)3, null}, |
| | | { cn2, "dc=test with long mod", mods4, true, AssuredMode.SAFE_READ_MODE, (byte)120, eclIncludes}, |
| | | { cn2, "dc=testDsaOperation", mods5, true, AssuredMode.SAFE_DATA_MODE, (byte)99, null}, |
| | | }; |
| | | } |
| | | |
| | |
| | | * create another ModifyMsg from the encoded byte array. |
| | | * Finally test that both Msg matches. |
| | | */ |
| | | @Test(dataProvider = "createModifyData") |
| | | @Test(enabled=true,dataProvider = "createModifyData") |
| | | public void modifyMsgTest(ChangeNumber changeNumber, |
| | | String rawdn, List<Modification> mods, |
| | | boolean isAssured, AssuredMode assuredMode, |
| | | byte safeDataLevel) |
| | | byte safeDataLevel, |
| | | List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | DN dn = DN.decode(rawdn); |
| | |
| | | msg.setAssuredMode(assuredMode); |
| | | msg.setSafeDataLevel(safeDataLevel); |
| | | |
| | | // Set ECL entry inlcuded attributes |
| | | if (entryAttrList != null) |
| | | { |
| | | msg.setEclIncludes(entryAttrList); |
| | | } |
| | | |
| | | ModifyMsg generatedMsg = (ModifyMsg) ReplicationMsg.generateMsg( |
| | | msg.getBytes(), ProtocolVersion.getCurrentVersion()); |
| | | |
| | |
| | | |
| | | assertEquals(msg.getChangeNumber(), generatedMsg.getChangeNumber()); |
| | | |
| | | // Get ECL entry attributes |
| | | ArrayList<RawAttribute> genAttrList = generatedMsg.getEclIncludes(); |
| | | if (entryAttrList==null) |
| | | assertTrue(genAttrList.size()==0); |
| | | else |
| | | { |
| | | assertTrue(genAttrList.size()==entryAttrList.size()); |
| | | int i=0; |
| | | for (Attribute attr : entryAttrList) |
| | | { |
| | | assertTrue(attr.getName().equalsIgnoreCase(genAttrList.get(i).toAttribute().getName())); |
| | | assertTrue(attr.toString().equalsIgnoreCase(genAttrList.get(i).toAttribute().toString()), |
| | | "Comparing: " + attr.toString() + " and " + genAttrList.get(i).toAttribute().toString()); |
| | | i++; |
| | | } |
| | | } |
| | | |
| | | Operation op = msg.createOperation(connection); |
| | | Operation generatedOperation = generatedMsg.createOperation(connection); |
| | | |
| | |
| | | * create another ModifyMsg from the encoded byte array. |
| | | * Finally test that both Msgs match. |
| | | */ |
| | | @Test(dataProvider = "createModifyData") |
| | | @Test(enabled=true,dataProvider = "createModifyData") |
| | | public void updateMsgTest(ChangeNumber changeNumber, |
| | | String rawdn, List<Modification> mods, |
| | | boolean isAssured, AssuredMode assuredMode, |
| | | byte safeDataLevel) |
| | | byte safeDataLevel , |
| | | List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | DN dn = DN.decode(rawdn); |
| | |
| | | * Build some data for the DeleteMsg test below. |
| | | */ |
| | | @DataProvider(name = "createDeleteData") |
| | | public Object[][] createDeleteData() { |
| | | public Object[][] createDeleteData() |
| | | { |
| | | |
| | | // Entry attributes |
| | | Attribute eattr1 = Attributes.create("description", "eav description"); |
| | | Attribute eattr2 = Attributes.create("namingcontexts", "eav naming contexts"); |
| | | List<Attribute> entryAttrList = new ArrayList<Attribute>(); |
| | | entryAttrList.add(eattr1); |
| | | entryAttrList.add(eattr2); |
| | | |
| | | return new Object[][] { |
| | | {"dc=com"}, |
| | | {"dc=delete,dc=an,dc=entry,dc=with,dc=a,dc=long dn"}, |
| | | {"dc=com", entryAttrList}, |
| | | {"dc=delete,dc=an,dc=entry,dc=with,dc=a,dc=long dn", null}, |
| | | }; |
| | | } |
| | | |
| | |
| | | * create another DeleteMsg from the encoded byte array. |
| | | * Finally test that both Msg matches. |
| | | */ |
| | | @Test(dataProvider = "createDeleteData") |
| | | public void deleteMsgTest(String rawDN) |
| | | throws Exception |
| | | @Test(enabled=true,dataProvider = "createDeleteData") |
| | | public void deleteMsgTest(String rawDN, List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | InternalClientConnection connection = |
| | | InternalClientConnection.getRootConnection(); |
| | |
| | | (short) 123, (short) 45); |
| | | op.setAttachment(SYNCHROCONTEXT, new DeleteContext(cn, "uniqueid")); |
| | | DeleteMsg msg = new DeleteMsg(op); |
| | | |
| | | // Set ECL entry attributes |
| | | if (entryAttrList != null) |
| | | { |
| | | msg.setEclIncludes(entryAttrList); |
| | | } |
| | | |
| | | DeleteMsg generatedMsg = (DeleteMsg) ReplicationMsg.generateMsg( |
| | | msg.getBytes(), ProtocolVersion.getCurrentVersion()); |
| | | |
| | |
| | | |
| | | assertEquals(msg.getChangeNumber(), generatedMsg.getChangeNumber()); |
| | | |
| | | // Get ECL entry attributes |
| | | ArrayList<RawAttribute> genAttrList = generatedMsg.getEclIncludes(); |
| | | if (entryAttrList==null) |
| | | assertTrue(genAttrList.size()==0); |
| | | else |
| | | { |
| | | assertTrue(genAttrList.size()==entryAttrList.size()); |
| | | int i=0; |
| | | for (Attribute attr : entryAttrList) |
| | | { |
| | | assertTrue(attr.getName().equalsIgnoreCase(genAttrList.get(i).toAttribute().getName())); |
| | | assertTrue(attr.toString().equalsIgnoreCase(genAttrList.get(i).toAttribute().toString()), |
| | | "Comparing: " + attr.toString() + " and " + genAttrList.get(i).toAttribute().toString()); |
| | | i++; |
| | | } |
| | | } |
| | | |
| | | Operation generatedOperation = generatedMsg.createOperation(connection); |
| | | |
| | | assertEquals(generatedOperation.getClass(), DeleteOperationBasis.class); |
| | |
| | | mods4.add(mod); |
| | | } |
| | | |
| | | // Entry attributes |
| | | Attribute eattr1 = Attributes.create("description", "eav description"); |
| | | Attribute eattr2 = Attributes.create("namingcontexts", "eav naming contexts"); |
| | | List<Attribute> entryAttrList = new ArrayList<Attribute>(); |
| | | entryAttrList.add(eattr1); |
| | | entryAttrList.add(eattr2); |
| | | |
| | | |
| | | return new Object[][] { |
| | | {"dc=test,dc=com", "dc=new", false, "dc=change", mods1, false, AssuredMode.SAFE_DATA_MODE, (byte)0}, |
| | | {"dc=test,dc=com", "dc=new", true, "dc=change", mods2, true, AssuredMode.SAFE_READ_MODE, (byte)1}, |
| | | {"dc=test,dc=com", "dc=new", false, "dc=change", mods1, false, AssuredMode.SAFE_DATA_MODE, (byte)0, entryAttrList}, |
| | | {"dc=test,dc=com", "dc=new", true, "dc=change", mods2, true, AssuredMode.SAFE_READ_MODE, (byte)1, null}, |
| | | // testNG does not like null argument so use "" for the newSuperior |
| | | // instead of null |
| | | {"dc=test,dc=com", "dc=new", false, "", mods3, true, AssuredMode.SAFE_READ_MODE, (byte)3}, |
| | | {"dc=test,dc=com", "dc=new", false, "", mods3, true, AssuredMode.SAFE_READ_MODE, (byte)3, entryAttrList}, |
| | | {"dc=delete,dc=an,dc=entry,dc=with,dc=a,dc=long dn", |
| | | "dc=new", true, "", mods4, true, AssuredMode.SAFE_DATA_MODE, (byte)99}, |
| | | "dc=new", true, "", mods4, true, AssuredMode.SAFE_DATA_MODE, (byte)99, null}, |
| | | }; |
| | | } |
| | | |
| | | @Test(dataProvider = "createModifyDnData") |
| | | @Test(enabled=true,dataProvider = "createModifyDnData") |
| | | public void modifyDnMsgTest(String rawDN, String newRdn, |
| | | boolean deleteOldRdn, String newSuperior, |
| | | List<Modification> mods, boolean isAssured, |
| | | AssuredMode assuredMode, |
| | | byte safeDataLevel) |
| | | byte safeDataLevel, List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | InternalClientConnection connection = |
| | |
| | | msg.setAssuredMode(assuredMode); |
| | | msg.setSafeDataLevel(safeDataLevel); |
| | | |
| | | // Set ECL entry attributes |
| | | if (entryAttrList != null) |
| | | { |
| | | msg.setEclIncludes(entryAttrList); |
| | | } |
| | | |
| | | ModifyDNMsg generatedMsg = (ModifyDNMsg) ReplicationMsg |
| | | .generateMsg(msg.getBytes(), ProtocolVersion.getCurrentVersion()); |
| | | |
| | |
| | | assertEquals(generatedMsg.getAssuredMode(), assuredMode); |
| | | assertEquals(generatedMsg.getSafeDataLevel(), safeDataLevel); |
| | | |
| | | // Get ECL entry attributes |
| | | ArrayList<RawAttribute> genAttrList = generatedMsg.getEclIncludes(); |
| | | if (entryAttrList==null) |
| | | assertTrue(genAttrList.size()==0); |
| | | else |
| | | { |
| | | assertTrue(genAttrList.size()==entryAttrList.size()); |
| | | int i=0; |
| | | for (Attribute attr : entryAttrList) |
| | | { |
| | | assertTrue(attr.getName().equalsIgnoreCase(genAttrList.get(i).toAttribute().getName())); |
| | | assertTrue(attr.toString().equalsIgnoreCase(genAttrList.get(i).toAttribute().toString()), |
| | | "Comparing: " + attr.toString() + " and " + genAttrList.get(i).toAttribute().toString()); |
| | | i++; |
| | | } |
| | | } |
| | | |
| | | Operation oriOp = msg.createOperation(connection); |
| | | Operation generatedOperation = generatedMsg.createOperation(connection); |
| | | |
| | |
| | | } |
| | | |
| | | @DataProvider(name = "createAddData") |
| | | public Object[][] createAddData() { |
| | | public Object[][] createAddData() |
| | | { |
| | | |
| | | // Entry attributes |
| | | Attribute eattr1 = Attributes.create("description", "eav description"); |
| | | Attribute eattr2 = Attributes.create("namingcontexts", "eav naming contexts"); |
| | | List<Attribute> entryAttrList = new ArrayList<Attribute>(); |
| | | entryAttrList.add(eattr1); |
| | | entryAttrList.add(eattr2); |
| | | return new Object[][] { |
| | | {"dc=example,dc=com", false, AssuredMode.SAFE_DATA_MODE, (byte)0}, |
| | | {"o=test", true, AssuredMode.SAFE_READ_MODE, (byte)1}, |
| | | {"o=group,dc=example,dc=com", true, AssuredMode.SAFE_READ_MODE, (byte)3}}; |
| | | {"dc=example,dc=com", false, AssuredMode.SAFE_DATA_MODE, (byte)0, entryAttrList}, |
| | | {"o=test", true, AssuredMode.SAFE_READ_MODE, (byte)1, null}, |
| | | {"o=group,dc=example,dc=com", true, AssuredMode.SAFE_READ_MODE, (byte)3, entryAttrList}}; |
| | | } |
| | | |
| | | @Test(dataProvider = "createAddData") |
| | | @Test(enabled=true,dataProvider = "createAddData") |
| | | public void addMsgTest(String rawDN, boolean isAssured, AssuredMode assuredMode, |
| | | byte safeDataLevel) |
| | | byte safeDataLevel, List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | Attribute objectClass = Attributes.create(DirectoryServer |
| | |
| | | msg.setAssuredMode(assuredMode); |
| | | msg.setSafeDataLevel(safeDataLevel); |
| | | |
| | | // Set ECL entry attributes |
| | | if (entryAttrList != null) |
| | | { |
| | | msg.setEclIncludes(entryAttrList); |
| | | } |
| | | |
| | | AddMsg generatedMsg = (AddMsg) ReplicationMsg.generateMsg(msg |
| | | .getBytes(), ProtocolVersion.getCurrentVersion()); |
| | | assertEquals(msg.getBytes(), generatedMsg.getBytes()); |
| | |
| | | assertEquals(generatedMsg.getAssuredMode(), assuredMode); |
| | | assertEquals(generatedMsg.getSafeDataLevel(), safeDataLevel); |
| | | |
| | | // Get ECL entry attributes |
| | | ArrayList<RawAttribute> genAttrList = generatedMsg.getEclIncludes(); |
| | | if (entryAttrList==null) |
| | | assertTrue(genAttrList.size()==0); |
| | | else |
| | | { |
| | | assertTrue(genAttrList.size()==entryAttrList.size()); |
| | | int i=0; |
| | | for (Attribute eattr : entryAttrList) |
| | | { |
| | | assertTrue(eattr.getName().equalsIgnoreCase(genAttrList.get(i).toAttribute().getName())); |
| | | assertTrue(eattr.toString().equalsIgnoreCase(genAttrList.get(i).toAttribute().toString()), |
| | | "Comparing: " + eattr.toString() + " and " + genAttrList.get(i).toAttribute().toString()); |
| | | i++; |
| | | } |
| | | } |
| | | |
| | | |
| | | // Create an new Add Operation from the current addMsg |
| | | InternalClientConnection connection = |
| | | InternalClientConnection.getRootConnection(); |
| | |
| | | generatedMsg.setAssuredMode(assuredMode); |
| | | generatedMsg.setSafeDataLevel(safeDataLevel); |
| | | |
| | | if (entryAttrList != null) |
| | | { |
| | | generatedMsg.setEclIncludes(entryAttrList); |
| | | } |
| | | |
| | | assertEquals(msg.getBytes(), generatedMsg.getBytes()); |
| | | assertEquals(msg.toString(), generatedMsg.toString()); |
| | | // TODO : should test that generated attributes match original attributes. |
| | |
| | | }; |
| | | } |
| | | |
| | | @Test(dataProvider = "createAckData") |
| | | @Test(enabled=true,dataProvider = "createAckData") |
| | | public void ackMsgTest(ChangeNumber cn, boolean hasTimeout, boolean hasWrongStatus, |
| | | boolean hasReplayError, List<Short> failedServers) |
| | | throws Exception |
| | |
| | | msg1.getBytes(), ProtocolVersion.getCurrentVersion()); |
| | | } |
| | | |
| | | @Test() |
| | | @Test(enabled=true) |
| | | public void eclUpdateMsg() |
| | | throws Exception |
| | | { |
| | |
| | | * Test that ServerStartMsg encoding and decoding works |
| | | * by checking that : msg == new ServerStartMsg(msg.getBytes()). |
| | | */ |
| | | @Test(dataProvider="createServerStartData") |
| | | @Test(enabled=true,dataProvider="createServerStartData") |
| | | public void serverStartMsgTest(short serverId, String baseDN, int window, |
| | | ServerState state, long genId, boolean sslEncryption, byte groupId) throws Exception |
| | | { |
| | |
| | | * Test that ReplServerStartMsg encoding and decoding works |
| | | * by checking that : msg == new ReplServerStartMsg(msg.getBytes()). |
| | | */ |
| | | @Test(dataProvider="createReplServerStartData") |
| | | @Test(enabled=true,dataProvider="createReplServerStartData") |
| | | public void replServerStartMsgTest(short serverId, String baseDN, int window, |
| | | String url, ServerState state, long genId, byte groupId, int degTh) throws Exception |
| | | { |
| | |
| | | urls4.add("ldaps://host:port/dc=foobar1??sub?(sn=Another Entry 1)"); |
| | | urls4.add("ldaps://host:port/dc=foobar2??sub?(sn=Another Entry 2)"); |
| | | |
| | | Set<String> a1 = new HashSet<String>(); |
| | | Set<String> a2 = new HashSet<String>(); |
| | | a2.add("dc"); |
| | | Set<String> a3 = new HashSet<String>(); |
| | | a3.add("dc"); |
| | | a3.add("uid"); |
| | | Set<String> a4 = new HashSet<String>(); |
| | | |
| | | DSInfo dsInfo1 = new DSInfo((short)13, (short)26, (long)154631, ServerStatus.FULL_UPDATE_STATUS, |
| | | false, AssuredMode.SAFE_DATA_MODE, (byte)12, (byte)132, urls1); |
| | | false, AssuredMode.SAFE_DATA_MODE, (byte)12, (byte)132, urls1, a1); |
| | | |
| | | DSInfo dsInfo2 = new DSInfo((short)-436, (short)493, (long)-227896, ServerStatus.DEGRADED_STATUS, |
| | | true, AssuredMode.SAFE_READ_MODE, (byte)-7, (byte)-265, urls2); |
| | | true, AssuredMode.SAFE_READ_MODE, (byte)-7, (byte)-265, urls2, a2); |
| | | |
| | | DSInfo dsInfo3 = new DSInfo((short)2436, (short)591, (long)0, ServerStatus.NORMAL_STATUS, |
| | | false, AssuredMode.SAFE_READ_MODE, (byte)17, (byte)0, urls3); |
| | | false, AssuredMode.SAFE_READ_MODE, (byte)17, (byte)0, urls3, a3); |
| | | |
| | | DSInfo dsInfo4 = new DSInfo((short)415, (short)146, (long)0, ServerStatus.BAD_GEN_ID_STATUS, |
| | | true, AssuredMode.SAFE_DATA_MODE, (byte)2, (byte)15, urls4); |
| | | true, AssuredMode.SAFE_DATA_MODE, (byte)2, (byte)15, urls4, a4); |
| | | |
| | | List<DSInfo> dsList1 = new ArrayList<DSInfo>(); |
| | | dsList1.add(dsInfo1); |
| | |
| | | rsList2.add(rsInfo3); |
| | | |
| | | return new Object [][] { |
| | | {dsList1, rsList1}, |
| | | {dsList2, rsList2}, |
| | | {dsList3, rsList1}, |
| | | {dsList3, null}, |
| | | {null, rsList1}, |
| | | {null, null}, |
| | | {dsList4, rsList2} |
| | | {dsList1, rsList1, a1}, |
| | | {dsList2, rsList2, a2}, |
| | | {dsList3, rsList1, a3}, |
| | | {dsList3, null, null}, |
| | | {null, rsList1, a1}, |
| | | {null, null, a2}, |
| | | {dsList4, rsList2, a3} |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * Test TopologyMsg encoding and decoding. |
| | | */ |
| | | @Test(dataProvider = "createTopologyData") |
| | | public void topologyMsgTest(List<DSInfo> dsList, List<RSInfo> rsList) |
| | | @Test(enabled=true,dataProvider = "createTopologyData") |
| | | public void topologyMsgTest(List<DSInfo> dsList, List<RSInfo> rsList, |
| | | Set<String> attrs) |
| | | throws Exception |
| | | { |
| | | TopologyMsg msg = new TopologyMsg(dsList, rsList); |
| | | TopologyMsg newMsg = new TopologyMsg(msg.getBytes()); |
| | | TopologyMsg newMsg = new TopologyMsg(msg.getBytes(), |
| | | ProtocolVersion.getCurrentVersion()); |
| | | assertEquals(msg.getDsList(), newMsg.getDsList()); |
| | | assertEquals(msg.getRsList(), newMsg.getRsList()); |
| | | } |
| | |
| | | urls6.add("ldaps://host:port/dc=foo??sub?(sn=Fourth Entry)"); |
| | | urls6.add("ldaps://host:port/dc=foo??sub?(sn=Fifth Entry)"); |
| | | |
| | | Set<String> a1 = new HashSet<String>(); |
| | | Set<String> a2 = new HashSet<String>(); |
| | | a2.add("dc"); |
| | | Set<String> a3 = new HashSet<String>(); |
| | | a3.add("dc"); |
| | | a3.add("uid"); |
| | | |
| | | return new Object[][]{ |
| | | {ServerStatus.NORMAL_STATUS, urls1, true, AssuredMode.SAFE_DATA_MODE, (byte)1}, |
| | | {ServerStatus.DEGRADED_STATUS, urls2, false, AssuredMode.SAFE_READ_MODE, (byte)123}, |
| | | {ServerStatus.FULL_UPDATE_STATUS, urls3, false, AssuredMode.SAFE_DATA_MODE, (byte)111}, |
| | | {ServerStatus.NORMAL_STATUS, urls4, true, AssuredMode.SAFE_READ_MODE, (byte)-1}, |
| | | {ServerStatus.DEGRADED_STATUS, urls5, true, AssuredMode.SAFE_DATA_MODE, (byte)97}, |
| | | {ServerStatus.FULL_UPDATE_STATUS, urls6, false, AssuredMode.SAFE_READ_MODE, (byte)-13} |
| | | {ServerStatus.NORMAL_STATUS, urls1, true, AssuredMode.SAFE_DATA_MODE, (byte)1, a1}, |
| | | {ServerStatus.DEGRADED_STATUS, urls2, false, AssuredMode.SAFE_READ_MODE, (byte)123, a2}, |
| | | {ServerStatus.FULL_UPDATE_STATUS, urls3, false, AssuredMode.SAFE_DATA_MODE, (byte)111, a3}, |
| | | {ServerStatus.NORMAL_STATUS, urls4, true, AssuredMode.SAFE_READ_MODE, (byte)-1, a1}, |
| | | {ServerStatus.DEGRADED_STATUS, urls5, true, AssuredMode.SAFE_DATA_MODE, (byte)97, a2}, |
| | | {ServerStatus.FULL_UPDATE_STATUS, urls6, false, AssuredMode.SAFE_READ_MODE, (byte)-13, a3} |
| | | }; |
| | | } |
| | | |
| | | /** |
| | | * Test StartSessionMsg encoding and decoding. |
| | | */ |
| | | @Test(dataProvider = "createStartSessionData") |
| | | @Test(enabled=true,dataProvider = "createStartSessionData") |
| | | public void startSessionMsgTest(ServerStatus status, List<String> refUrls, |
| | | boolean assuredFlag, AssuredMode assuredMode, byte safedataLevel) |
| | | boolean assuredFlag, AssuredMode assuredMode, byte safedataLevel, |
| | | Set<String> attrs) |
| | | throws Exception |
| | | { |
| | | StartSessionMsg msg = new StartSessionMsg(status, refUrls, assuredFlag, |
| | | assuredMode, safedataLevel); |
| | | StartSessionMsg newMsg = new StartSessionMsg(msg.getBytes()); |
| | | msg.setEclIncludes(attrs); |
| | | StartSessionMsg newMsg = |
| | | new StartSessionMsg(msg.getBytes(),ProtocolVersion.getCurrentVersion()); |
| | | assertEquals(msg.getStatus(), newMsg.getStatus()); |
| | | assertTrue(msg.isAssured() == newMsg.isAssured()); |
| | | assertEquals(msg.getAssuredMode(), newMsg.getAssuredMode()); |
| | | assertTrue(msg.getSafeDataLevel() == newMsg.getSafeDataLevel()); |
| | | assertEquals(msg.getReferralsURLs(), newMsg.getReferralsURLs()); |
| | | Set<String> newAttrs = newMsg.getEclIncludes(); |
| | | assertTrue(attrs.size() == newAttrs.size()); |
| | | } |
| | | |
| | | /** |
| | |
| | | /** |
| | | * Test ChangeStatusMsg encoding and decoding. |
| | | */ |
| | | @Test(dataProvider = "createChangeStatusData") |
| | | @Test(enabled=true,dataProvider = "createChangeStatusData") |
| | | public void changeStatusMsgTest(ServerStatus reqStatus, ServerStatus newStatus) |
| | | throws Exception |
| | | { |
| | |
| | | * Test that ServerStartMsg encoding and decoding works |
| | | * by checking that : msg == new ServerStartMsg(msg.getBytes()). |
| | | */ |
| | | @Test(dataProvider="createServerStartData") |
| | | @Test(enabled=true,dataProvider="createServerStartData") |
| | | public void startECLMsgTest(short serverId, String baseDN, int window, |
| | | ServerState state, long genId, boolean sslEncryption, byte groupId) throws Exception |
| | | { |
| | |
| | | assertTrue(dn1found); |
| | | assertTrue(dn2found); |
| | | } |
| | | |
| | | int perfRep = 100000; |
| | | |
| | | |
| | | @Test(enabled=false,dataProvider = "createAddData") |
| | | public void addMsgPerfs(String rawDN, boolean isAssured, AssuredMode assuredMode, |
| | | byte safeDataLevel, List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | long createop = 0; |
| | | long createmsgfromop = 0; |
| | | long encodemsg = 0; |
| | | long getbytes = 0; |
| | | long alld = 0; |
| | | long setentryattr = 0; |
| | | long buildnew = 0; |
| | | long t1,t2,t3,t31,t4,t5,t6 = 0; |
| | | |
| | | HashMap<ObjectClass, String> objectClassList = new HashMap<ObjectClass, String>(); |
| | | objectClassList.put(DirectoryServer.getObjectClass("organization"), |
| | | "organization"); |
| | | |
| | | ArrayList<Attribute> userAttributes = new ArrayList<Attribute>(1); |
| | | Attribute attr = Attributes.create("o", "com"); |
| | | userAttributes.add(attr); |
| | | HashMap<AttributeType, List<Attribute>> userAttList = new HashMap<AttributeType, List<Attribute>>(); |
| | | userAttList.put(attr.getAttributeType(), userAttributes); |
| | | |
| | | |
| | | ArrayList<Attribute> operationalAttributes = new ArrayList<Attribute>(1); |
| | | attr = Attributes.create("creatorsname", "dc=creator"); |
| | | operationalAttributes.add(attr); |
| | | HashMap<AttributeType,List<Attribute>> opList= |
| | | new HashMap<AttributeType,List<Attribute>>(); |
| | | opList.put(attr.getAttributeType(), operationalAttributes); |
| | | |
| | | ChangeNumber cn = new ChangeNumber(TimeThread.getTime(), |
| | | (short) 123, (short) 45); |
| | | DN dn = DN.decode(rawDN); |
| | | |
| | | for (int i=1;i<perfRep;i++) |
| | | { |
| | | t1 = System.nanoTime(); |
| | | |
| | | // create op |
| | | AddOperation addOpB = new AddOperationBasis(connection, |
| | | (long) 1, 1, null, dn, objectClassList, userAttList, opList); |
| | | LocalBackendAddOperation addOp = new LocalBackendAddOperation(addOpB); |
| | | OperationContext opCtx = new AddContext(cn, "thisIsaUniqueID", |
| | | "parentUniqueId"); |
| | | addOp.setAttachment(SYNCHROCONTEXT, opCtx); |
| | | t2 = System.nanoTime(); |
| | | createop += (t2 - t1); |
| | | |
| | | // create msg from op |
| | | AddMsg generatedMsg = new AddMsg(addOp); |
| | | t3 = System.nanoTime(); |
| | | createmsgfromop += (t3 - t2); |
| | | |
| | | // set entry attr |
| | | generatedMsg.setEclIncludes(entryAttrList); |
| | | t31 = System.nanoTime(); |
| | | setentryattr += (t31 - t3); |
| | | |
| | | // encode msg |
| | | generatedMsg.encode(); |
| | | t4 = System.nanoTime(); |
| | | encodemsg += (t4 - t31); |
| | | |
| | | // getBytes |
| | | byte[] bytes = generatedMsg.getBytes(ProtocolVersion.getCurrentVersion()); |
| | | t5 = System.nanoTime(); |
| | | getbytes += (t5 - t4); |
| | | |
| | | // getBytes |
| | | new AddMsg(bytes); |
| | | t6 = System.nanoTime(); |
| | | buildnew += (t6 - t5); |
| | | |
| | | alld += (t6 - t1); |
| | | } |
| | | |
| | | System.out.println( |
| | | "addMsgPerfs " |
| | | + "createop\t" |
| | | + "createmsgfromop\t" |
| | | + "setentryattr\t" |
| | | + "encodemsg\t" |
| | | + "getbytes\t" |
| | | + "buildnew\t"); |
| | | |
| | | System.out.println( |
| | | "addMsgPerfs " |
| | | + createop/perfRep/1000.0 + " μs \t" |
| | | + createmsgfromop/perfRep/1000.0 + " μs \t" |
| | | + setentryattr/perfRep/1000.0 + " μs \t" |
| | | + encodemsg/perfRep/1000.0 + " μs \t" |
| | | + getbytes/perfRep/1000.0 + " μs \t" |
| | | + buildnew/perfRep/1000.0 + " μs \t"); |
| | | } |
| | | |
| | | @Test(enabled=false,dataProvider = "createModifyData") |
| | | public void modMsgPerfs(ChangeNumber changeNumber, |
| | | String rawdn, List<Modification> mods, |
| | | boolean isAssured, AssuredMode assuredMode, |
| | | byte safeDataLevel, List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | long createop = 0; |
| | | long createmsgfromop = 0; |
| | | long encodemsg = 0; |
| | | long getbytes = 0; |
| | | long alld = 0; |
| | | long setentryattr = 0; |
| | | long buildnew = 0; |
| | | long t1,t2,t3,t31,t4,t5,t6 = 0; |
| | | |
| | | ChangeNumber cn = new ChangeNumber(TimeThread.getTime(), |
| | | (short) 123, (short) 45); |
| | | DN dn = DN.decode(rawdn); |
| | | |
| | | for (int i=1;i<perfRep;i++) |
| | | { |
| | | t1 = System.nanoTime(); |
| | | |
| | | // create op |
| | | ModifyOperation modifyOpB = new ModifyOperationBasis( |
| | | connection, (long)1, 1, null, dn, mods); |
| | | LocalBackendModifyOperation modifyOp = |
| | | new LocalBackendModifyOperation(modifyOpB); |
| | | OperationContext opCtx = new ModifyContext(cn, "thisIsaUniqueID"); |
| | | modifyOp.setAttachment(SYNCHROCONTEXT, opCtx); |
| | | t2 = System.nanoTime(); |
| | | createop += (t2 - t1); |
| | | |
| | | // create msg from op |
| | | ModifyMsg generatedMsg = new ModifyMsg(modifyOp); |
| | | t3 = System.nanoTime(); |
| | | createmsgfromop += (t3 - t2); |
| | | |
| | | // set entry attr |
| | | // generatedMsg.setEntryAttributes(entryAttrList); |
| | | t31 = System.nanoTime(); |
| | | setentryattr += (t31 - t3); |
| | | |
| | | // encode msg |
| | | generatedMsg.encode(); |
| | | t4 = System.nanoTime(); |
| | | encodemsg += (t4 - t31); |
| | | |
| | | // getBytes |
| | | byte[] bytes = generatedMsg.getBytes(ProtocolVersion.getCurrentVersion()); |
| | | t5 = System.nanoTime(); |
| | | getbytes += (t5 - t4); |
| | | |
| | | // getBytes |
| | | new ModifyMsg(bytes); |
| | | t6 = System.nanoTime(); |
| | | buildnew += (t6 - t5); |
| | | |
| | | alld += (t6 - t1); |
| | | } |
| | | |
| | | System.out.println( |
| | | "modMsgPerfs " |
| | | + "createop\t" |
| | | + "createmsgfromop\t" |
| | | + "setentryattr\t" |
| | | + "encodemsg\t" |
| | | + "getbytes\t" |
| | | + "buildnew\t"); |
| | | |
| | | System.out.println( |
| | | "modMsgPerfs " |
| | | + createop/perfRep/1000.0 + " μs \t" |
| | | + createmsgfromop/perfRep/1000.0 + " μs \t" |
| | | + setentryattr/perfRep/1000.0 + " μs \t" |
| | | + encodemsg/perfRep/1000.0 + " μs \t" |
| | | + getbytes/perfRep/1000.0 + " μs \t" |
| | | + buildnew/perfRep/1000.0 + " μs \t"); |
| | | } |
| | | |
| | | @Test(enabled=false,dataProvider = "createDeleteData") |
| | | public void deleteMsgPerfs(String rawDN, List<Attribute> entryAttrList) |
| | | throws Exception |
| | | { |
| | | InternalClientConnection connection = |
| | | InternalClientConnection.getRootConnection(); |
| | | |
| | | long createop = 0; |
| | | long createmsgfromop = 0; |
| | | long encodemsg = 0; |
| | | long getbytes = 0; |
| | | long alld = 0; |
| | | long setentryattr = 0; |
| | | long buildnew = 0; |
| | | long t1,t2,t3,t31,t4,t5,t6 = 0; |
| | | |
| | | for (int i=1;i<perfRep;i++) |
| | | { |
| | | t1 = System.nanoTime(); |
| | | |
| | | // create op |
| | | DeleteOperationBasis opBasis = |
| | | new DeleteOperationBasis(connection, 1, 1,null, DN.decode(rawDN)); |
| | | LocalBackendDeleteOperation op = new LocalBackendDeleteOperation(opBasis); |
| | | ChangeNumber cn = new ChangeNumber(TimeThread.getTime(), |
| | | (short) 123, (short) 45); |
| | | op.setAttachment(SYNCHROCONTEXT, new DeleteContext(cn, "uniqueid")); |
| | | t2 = System.nanoTime(); |
| | | createop += (t2 - t1); |
| | | |
| | | // create msg from op |
| | | DeleteMsg generatedMsg = new DeleteMsg(op); |
| | | t3 = System.nanoTime(); |
| | | createmsgfromop += (t3 - t2); |
| | | |
| | | // set entry attr |
| | | //generatedMsg.setEntryAttributes(entryAttrList); |
| | | t31 = System.nanoTime(); |
| | | setentryattr += (t31 - t3); |
| | | |
| | | // encode msg |
| | | generatedMsg.encode(); |
| | | t4 = System.nanoTime(); |
| | | encodemsg += (t4 - t31); |
| | | |
| | | // getBytes |
| | | byte[] bytes = generatedMsg.getBytes(ProtocolVersion.getCurrentVersion()); |
| | | t5 = System.nanoTime(); |
| | | getbytes += (t5 - t4); |
| | | |
| | | // getBytes |
| | | new DeleteMsg(bytes); |
| | | t6 = System.nanoTime(); |
| | | buildnew += (t6 - t5); |
| | | |
| | | alld += (t6 - t1); |
| | | } |
| | | |
| | | System.out.println( |
| | | "deleteMsgPerfs " |
| | | + "createop\t" |
| | | + "createmsgfromop\t" |
| | | + "setentryattr\t" |
| | | + "encodemsg\t" |
| | | + "getbytes\t" |
| | | + "buildnew\t"); |
| | | |
| | | System.out.println( |
| | | "deleteMsgPerfs " |
| | | + createop/perfRep/1000.0 + " μs \t" |
| | | + createmsgfromop/perfRep/1000.0 + " μs \t" |
| | | + setentryattr/perfRep/1000.0 + " μs \t" |
| | | + encodemsg/perfRep/1000.0 + " μs \t" |
| | | + getbytes/perfRep/1000.0 + " μs \t" |
| | | + buildnew/perfRep/1000.0 + " μs \t"); |
| | | } |
| | | } |
| | |
| | | protected void importBackend(InputStream input) throws DirectoryException |
| | | { |
| | | byte[] buffer = new byte[1000]; |
| | | |
| | | int ret; |
| | | do |
| | | { |
| | |
| | | ResultCode.OPERATIONS_ERROR, |
| | | ERR_BACKEND_EXPORT_ENTRY.get("", "")); |
| | | } |
| | | importString.append(new String(buffer, 0, ret)); |
| | | if (ret>0) |
| | | importString.append(new String(buffer, 0, ret)); |
| | | } |
| | | while (ret >= 0); |
| | | } |
| | |
| | | assertTrue(replServerInfo.getGenerationId() == 2); |
| | | } |
| | | |
| | | for (DSInfo serverInfo : domain1.getReplicasList()) |
| | | int sleepTime = 50; |
| | | while (true) |
| | | { |
| | | if (serverInfo.getDsId() == domain2ServerId) |
| | | assertEquals(serverInfo.getStatus(), ServerStatus.BAD_GEN_ID_STATUS); |
| | | else |
| | | try |
| | | { |
| | | assertTrue(serverInfo.getDsId() == domain1ServerId); |
| | | assertTrue(serverInfo.getStatus() == ServerStatus.NORMAL_STATUS); |
| | | } |
| | | } |
| | | for (DSInfo serverInfo : domain1.getReplicasList()) |
| | | { |
| | | if (serverInfo.getDsId() == domain2ServerId) |
| | | assertEquals(serverInfo.getStatus(), ServerStatus.BAD_GEN_ID_STATUS); |
| | | else |
| | | { |
| | | assertTrue(serverInfo.getDsId() == domain1ServerId); |
| | | assertTrue(serverInfo.getStatus() == ServerStatus.NORMAL_STATUS); |
| | | } |
| | | } |
| | | |
| | | for (DSInfo serverInfo : domain2.getReplicasList()) |
| | | { |
| | | if (serverInfo.getDsId() == domain2ServerId) |
| | | assertTrue(serverInfo.getStatus() == ServerStatus.BAD_GEN_ID_STATUS); |
| | | else |
| | | for (DSInfo serverInfo : domain2.getReplicasList()) |
| | | { |
| | | if (serverInfo.getDsId() == domain2ServerId) |
| | | assertTrue(serverInfo.getStatus() == ServerStatus.BAD_GEN_ID_STATUS); |
| | | else |
| | | { |
| | | assertTrue(serverInfo.getDsId() == domain1ServerId); |
| | | assertTrue(serverInfo.getStatus() == ServerStatus.NORMAL_STATUS); |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | catch (AssertionError e) |
| | | { |
| | | assertTrue(serverInfo.getDsId() == domain1ServerId); |
| | | assertTrue(serverInfo.getStatus() == ServerStatus.NORMAL_STATUS); |
| | | } |
| | | if (sleepTime < 30000) |
| | | { |
| | | Thread.sleep(sleepTime); |
| | | sleepTime *=2; |
| | | } |
| | | else |
| | | throw e; |
| | | } |
| | | } |
| | | |
| | | Map<Short, ServerState> states1 = domain1.getReplicaStates(); |
| | | ServerState state2 = states1.get(domain2ServerId); |
| | | assertNotNull(state2, "getReplicaStates is not showing DS2"); |