Partial fix OPENDJ-194: Minor improvements to change log content and configuration
Publish original attributes from the target entry as a single value LDIF blob in "includedAttributes" in a similar manner to the "changes" attribute.
| | |
| | | ds-cfg-global-aci: (extop="1.3.6.1.4.1.26027.1.6.1 || 1.3.6.1.4.1.26027.1.6.3 || 1.3.6.1.4.1.4203.1.11.1 || 1.3.6.1.4.1.1466.20037 || 1.3.6.1.4.1.4203.1.11.3") (version 3.0; acl "Anonymous extended operation access"; allow(read) userdn="ldap:///anyone";) |
| | | ds-cfg-global-aci: (targetcontrol="2.16.840.1.113730.3.4.2 || 2.16.840.1.113730.3.4.17 || 2.16.840.1.113730.3.4.19 || 1.3.6.1.4.1.4203.1.10.2 || 1.3.6.1.4.1.42.2.27.8.5.1 || 2.16.840.1.113730.3.4.16") (version 3.0; acl "Anonymous control access"; allow(read) userdn="ldap:///anyone";) |
| | | ds-cfg-global-aci: (targetcontrol="1.3.6.1.1.12 || 1.3.6.1.1.13.1 || 1.3.6.1.1.13.2 || 1.2.840.113556.1.4.319 || 1.2.826.0.1.3344810.2.3 || 2.16.840.1.113730.3.4.18 || 2.16.840.1.113730.3.4.9 || 1.2.840.113556.1.4.473 || 1.3.6.1.4.1.42.2.27.9.5.9") (version 3.0; acl "Authenticated users control access"; allow(read) userdn="ldap:///all";) |
| | | ds-cfg-global-aci: (targetattr!="userPassword||authPassword||changes||changeNumber||changeType||changeTime||targetDN||newRDN||newSuperior||deleteOldRDN||targetEntryUUID||changeInitiatorsName||changeLogCookie")(version 3.0; acl "Anonymous read access"; allow (read,search,compare) userdn="ldap:///anyone";) |
| | | ds-cfg-global-aci: (targetattr!="userPassword||authPassword||changes||changeNumber||changeType||changeTime||targetDN||newRDN||newSuperior||deleteOldRDN||targetEntryUUID||changeInitiatorsName||changeLogCookie||includedAttributes")(version 3.0; acl "Anonymous read access"; allow (read,search,compare) userdn="ldap:///anyone";) |
| | | ds-cfg-global-aci: (targetattr="audio||authPassword||description||displayName||givenName||homePhone||homePostalAddress||initials||jpegPhoto||labeledURI||mobile||pager||postalAddress||postalCode||preferredLanguage||telephoneNumber||userPassword")(version 3.0; acl "Self entry modification"; allow (write) userdn="ldap:///self";) |
| | | ds-cfg-global-aci: (targetattr="userPassword||authPassword")(version 3.0; acl "Self entry read"; allow (read,search,compare) userdn="ldap:///self";) |
| | | ds-cfg-global-aci: (target="ldap:///cn=schema")(targetscope="base")(targetattr="objectClass||attributeTypes||dITContentRules||dITStructureRules||ldapSyntaxes||matchingRules||matchingRuleUse||nameForms||objectClasses")(version 3.0; acl "User-Visible Schema Operational Attributes"; allow (read,search,compare) userdn="ldap:///anyone";) |
| | |
| | | SINGLE-VALUE |
| | | USAGE directoryOperation |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.6 NAME 'includedAttributes' |
| | | DESC 'A set of attributes which were part of the entry before the changes were applied' |
| | | SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 |
| | | SINGLE-VALUE |
| | | USAGE directoryOperation |
| | | X-ORIGIN 'OpenDJ Directory Server' ) |
| | | objectClasses: ( 2.16.840.1.113730.3.2.1 NAME 'changeLogEntry' SUP top |
| | | STRUCTURAL |
| | | MUST ( changeNumber $ targetDN $ changeType $ changeTime ) |
| | |
| | | |
| | | |
| | | import static org.opends.messages.CoreMessages.*; |
| | | import static org.opends.messages.ReplicationMessages.*; |
| | | import static org.opends.server.config.ConfigConstants.*; |
| | | import static org.opends.server.loggers.ErrorLogger.logError; |
| | | import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; |
| | |
| | | .getCookie().toString(), DN.decode(addMsg.getDn()), |
| | | addMsg.getChangeNumber(), ldifChanges, // entry as created (in LDIF |
| | | // format) |
| | | addMsg.getUniqueId(), null, // real time current entry |
| | | addMsg.getUniqueId(), |
| | | eclAttributes, // entry attributes |
| | | eclmsg.getDraftChangeNumber(), "add", changeInitiatorsName); |
| | | |
| | |
| | | .getCookie().toString(), DN.decode(modifyMsg.getDn()), |
| | | modifyMsg.getChangeNumber(), ldifChanges, |
| | | modifyMsg.getUniqueId(), |
| | | null, // real time current entry |
| | | modifyMsg.getEclIncludes(), // entry attributes |
| | | eclmsg.getDraftChangeNumber(), changeType, |
| | | changeInitiatorsName); |
| | |
| | | .getCookie().toString(), DN.decode(delMsg.getDn()), |
| | | delMsg.getChangeNumber(), |
| | | null, // no changes |
| | | delMsg.getUniqueId(), null, |
| | | delMsg.getUniqueId(), |
| | | delMsg.getEclIncludes(), // entry attributes |
| | | eclmsg.getDraftChangeNumber(), "delete", |
| | | delMsg.getInitiatorsName()); |
| | |
| | | * @param changeNumber The provided replication changeNumber. |
| | | * @param clearLDIFchanges The provided LDIF changes for ADD and MODIFY |
| | | * @param targetUUID The provided targetUUID. |
| | | * @param entry The provided related current entry. |
| | | * @param histEntryAttributes TODO:ECL Adress hist entry attributes |
| | | * @param includedAttributes TODO:ECL Adress hist entry attributes |
| | | * @param draftChangenumber The provided draft change number (integer) |
| | | * @param changetype The provided change type (add, ...) |
| | | * @param changeInitiatorsName The provided initiatiors name |
| | |
| | | ChangeNumber changeNumber, |
| | | String clearLDIFchanges, |
| | | String targetUUID, |
| | | Entry entry, |
| | | List<RawAttribute> histEntryAttributes, |
| | | List<RawAttribute> includedAttributes, |
| | | int draftChangenumber, |
| | | String changetype, |
| | | String changeInitiatorsName) |
| | |
| | | else |
| | | uAttrs.put(aType, attrList); |
| | | |
| | | if (histEntryAttributes != null) |
| | | if (includedAttributes != null && !includedAttributes.isEmpty()) |
| | | { |
| | | for (RawAttribute ra : histEntryAttributes) |
| | | StringBuilder builder = new StringBuilder(256); |
| | | for (RawAttribute includedAttribute : includedAttributes) |
| | | { |
| | | try |
| | | String name = includedAttribute.getAttributeType(); |
| | | for (ByteString value : includedAttribute.getValues()) |
| | | { |
| | | String attrName = ra.getAttributeType().toLowerCase(); |
| | | String eclName = "target" + attrName; |
| | | 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(builder.toAttribute()); |
| | | uAttrs.put(at, attrList); |
| | | builder.append(name); |
| | | appendLDIFSeparatorAndValue(builder, value); |
| | | builder.append('\n'); |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | } |
| | | String includedAttributesLDIF = builder.toString(); |
| | | |
| | | } |
| | | if ((aType = DirectoryServer |
| | | .getAttributeType("includedattributes")) == null) |
| | | { |
| | | aType = DirectoryServer |
| | | .getDefaultAttributeType("includedAttributes"); |
| | | } |
| | | a = Attributes.create(aType, includedAttributesLDIF); |
| | | attrList = new ArrayList<Attribute>(1); |
| | | attrList.add(a); |
| | | |
| | | if (aType.isOperational()) |
| | | { |
| | | operationalAttrs.put(aType, attrList); |
| | | } |
| | | else |
| | | { |
| | | uAttrs.put(aType, attrList); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | <script> |
| | | CurrentTestPath['group']='aci' |
| | | GLOBAL_ACI_SEARCH="(targetattr!=\"userPassword||authPassword||changes||changeNumber||changeType||changeTime||targetDN||newRDN||newSuperior||deleteOldRDN||targetEntryUUID||changeInitiatorsName||changeLogCookie\")(version 3.0; acl \"Anonymous read access\"; allow (read,search,compare) userdn=\"ldap:///anyone\";)" |
| | | GLOBAL_ACI_SEARCH="(targetattr!=\"userPassword||authPassword||changes||changeNumber||changeType||changeTime||targetDN||newRDN||newSuperior||deleteOldRDN||targetEntryUUID||changeInitiatorsName||changeLogCookie||includedAttributes\")(version 3.0; acl \"Anonymous read access\"; allow (read,search,compare) userdn=\"ldap:///anyone\";)" |
| | | </script> |
| | | |
| | | <call function="'testGroup_Preamble'"/> |
| | |
| | | CurrentTestPath['group']='privileges' |
| | | _group=CurrentTestPath['group'] |
| | | |
| | | GLOBAL_ACI_SEARCH="(targetattr!=\"userPassword||authPassword||changes||changeNumber||changeType||changeTime||targetDN||newRDN||newSuperior||deleteOldRDN||targetEntryUUID||changeInitiatorsName||changeLogCookie\")(version 3.0; acl \"Anonymous read access\"; allow (read,search,compare) userdn=\"ldap:///anyone\";)" |
| | | GLOBAL_ACI_SEARCH="(targetattr!=\"userPassword||authPassword||changes||changeNumber||changeType||changeTime||targetDN||newRDN||newSuperior||deleteOldRDN||targetEntryUUID||changeInitiatorsName||changeLogCookie||includedAttributes\")(version 3.0; acl \"Anonymous read access\"; allow (read,search,compare) userdn=\"ldap:///anyone\";)" |
| | | </script> |
| | | <call function="'testGroup_Preamble'" /> |
| | | <script> |
| | |
| | | CurrentTestPath['group']='security' |
| | | _group=CurrentTestPath['group'] |
| | | |
| | | GLOBAL_ACI_SEARCH="(targetattr!=\"userPassword||authPassword||changes||changeNumber||changeType||changeTime||targetDN||newRDN||newSuperior||deleteOldRDN||targetEntryUUID||changeInitiatorsName||changeLogCookie\")(version 3.0; acl \"Anonymous read access\"; allow (read,search,compare) userdn=\"ldap:///anyone\";)" |
| | | GLOBAL_ACI_SEARCH="(targetattr!=\"userPassword||authPassword||changes||changeNumber||changeType||changeTime||targetDN||newRDN||newSuperior||deleteOldRDN||targetEntryUUID||changeInitiatorsName||changeLogCookie||includedAttributes\")(version 3.0; acl \"Anonymous read access\"; allow (read,search,compare) userdn=\"ldap:///anyone\";)" |
| | | </script> |
| | | <call function="'testGroup_Preamble'" /> |
| | | <script> |
| | |
| | | * Launcher. |
| | | */ |
| | | @Test(enabled=true) |
| | | public void ECLReplicationServerTest() |
| | | public void ECLReplicationServerTest() throws Exception |
| | | { |
| | | // No RSDomain created yet => RS only case => ECL is not a supported |
| | | ECLIsNotASupportedSuffix(); |
| | |
| | | * Test ECl entry attributes, and there configuration. |
| | | * |
| | | */ |
| | | private void ECLIncludeAttributes() |
| | | private void ECLIncludeAttributes() throws Exception |
| | | { |
| | | String tn = "ECLIncludeAttributes"; |
| | | debugInfo(tn, "Starting test\n\n"); |
| | |
| | | s += "Entry:" + resultEntry.toLDIFString(); |
| | | |
| | | String targetdn = getAttributeValue(resultEntry, "targetdn"); |
| | | |
| | | if ((targetdn.endsWith("cn=robert hue,o=test3")) |
| | | ||(targetdn.endsWith("cn=robert hue2,o=test3"))) |
| | | { |
| | | Entry targetEntry = parseIncludedAttributes(resultEntry, |
| | | targetdn); |
| | | |
| | | HashSet<String> eoc = new HashSet<String>(); |
| | | eoc.add("person");eoc.add("inetOrgPerson");eoc.add("organizationalPerson");eoc.add("top"); |
| | | checkValues(resultEntry,"targetobjectclass",eoc); |
| | | assertEquals(targetEntry.getAttributes().size(), 0); // objectClass is handled separately |
| | | checkValues(targetEntry,"objectclass",eoc); |
| | | } |
| | | if (targetdn.endsWith("cn=fiona jensen,o=test2")) |
| | | { |
| | | checkValue(resultEntry,"targetsn","jensen"); |
| | | checkValue(resultEntry,"targetcn","Fiona Jensen"); |
| | | Entry targetEntry = parseIncludedAttributes(resultEntry, |
| | | targetdn); |
| | | |
| | | assertEquals(targetEntry.getAttributes().size(), 2); |
| | | checkValue(targetEntry,"sn","jensen"); |
| | | checkValue(targetEntry,"cn","Fiona Jensen"); |
| | | } |
| | | checkValue(resultEntry,"changeinitiatorsname", "cn=Internal Client,cn=Root DNs,cn=config"); |
| | | } |
| | | } |
| | | assertEquals(entries.size(),8, "Entries number returned by search" + s); |
| | | } |
| | | catch(Exception e) |
| | | { |
| | | fail("Ending "+tn+" test with exception:\n" |
| | | + stackTraceToSingleLineString(e)); |
| | | } |
| | | finally |
| | | { |
| | | try |
| | |
| | | debugInfo(tn, "Ending test with success"); |
| | | } |
| | | |
| | | private Entry parseIncludedAttributes( |
| | | SearchResultEntry resultEntry, String targetdn) |
| | | throws Exception |
| | | { |
| | | // Parse includedAttributes as an entry. |
| | | String includedAttributes = getAttributeValue(resultEntry, "includedattributes"); |
| | | String[] ldifAttributeLines = includedAttributes.split("\\n"); |
| | | String[] ldif = new String[ldifAttributeLines.length + 1]; |
| | | System.arraycopy(ldifAttributeLines, 0, ldif, 1, ldifAttributeLines.length); |
| | | ldif[0] = "dn: " + targetdn; |
| | | Entry targetEntry = TestCaseUtils.makeEntry(ldif); |
| | | return targetEntry; |
| | | } |
| | | |
| | | private void waitOpResult(AbstractOperation operation, |
| | | ResultCode expectedResult) |
| | | { |