diff --git a/src/main/java/net/tirasa/connid/bundles/ldap/sync/GenericChangeLogSyncStrategy.java b/src/main/java/net/tirasa/connid/bundles/ldap/sync/GenericChangeLogSyncStrategy.java index e9fe667..f99d0f9 100644 --- a/src/main/java/net/tirasa/connid/bundles/ldap/sync/GenericChangeLogSyncStrategy.java +++ b/src/main/java/net/tirasa/connid/bundles/ldap/sync/GenericChangeLogSyncStrategy.java @@ -55,6 +55,7 @@ import org.identityconnectors.framework.common.exceptions.ConnectorException; import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.AttributeBuilder; +import org.identityconnectors.framework.common.objects.AttributeUtil; import org.identityconnectors.framework.common.objects.AttributesAccessor; import org.identityconnectors.framework.common.objects.ConnectorObject; import org.identityconnectors.framework.common.objects.ConnectorObjectBuilder; @@ -79,7 +80,7 @@ public class GenericChangeLogSyncStrategy implements LdapSyncStrategy { // TODO detect that the change log has been trimmed. - protected static final Log LOG = Log.getLog(GenericChangeLogSyncStrategy.class); + protected static final Log LOG = Log.getLog(LdapSyncStrategy.class); /** * The list of attribute operations supported by the "modify" LDIF change type. @@ -110,7 +111,7 @@ public class GenericChangeLogSyncStrategy implements LdapSyncStrategy { public GenericChangeLogSyncStrategy(LdapConnection conn) { this.conn = conn; } - + protected SyncToken getLatestSyncTokenPaged(ObjectClass oclass, OperationOptionsBuilder builder) { LOG.ok("Getting latest sync token with pages of size {0}", conn.getConfiguration().getChangeLogBlockSize()); @@ -126,12 +127,15 @@ protected SyncToken getLatestSyncTokenPaged(ObjectClass oclass, OperationOptions cookies[0] = null; SearchResultsHandler handler = new SearchResultsHandler() { + @Override public boolean handle(final ConnectorObject object) { - int changeNumber = convertToInt( - (String) object.getAttributeByName(getChangeNumberAttribute()).getValue().get(0), -1); - if (changeNumber > maxChangeNumber[0]) { - maxChangeNumber[0] = changeNumber; + Attribute changeNumberAttr = object.getAttributeByName(getChangeNumberAttribute()); + if (changeNumberAttr != null) { + int changeNumber = convertToInt(AttributeUtil.getStringValue(changeNumberAttr), -1); + if (changeNumber > maxChangeNumber[0]) { + maxChangeNumber[0] = changeNumber; + } } return true; @@ -157,15 +161,17 @@ public void handleResult(final SearchResult result) { return new SyncToken(maxChangeNumber[0]); } - + protected SyncToken getLatestSyncTokenDefault(ObjectClass oclass, OperationOptionsBuilder builder) { final int[] maxChangeNumber = { 0 }; LOG.ok("Getting latest sync token with a regular search"); ResultsHandler handler = new ResultsHandler() { + @Override public boolean handle(final ConnectorObject object) { - int changeNumber = convertToInt((String) object.getAttributeByName(getChangeNumberAttribute()).getValue().get(0), -1); + int changeNumber = convertToInt((String) object.getAttributeByName(getChangeNumberAttribute()). + getValue().get(0), -1); if (changeNumber > maxChangeNumber[0]) { maxChangeNumber[0] = changeNumber; } @@ -180,7 +186,7 @@ public boolean handle(final ConnectorObject object) { handler, builder.build(), conn.getConfiguration().getChangeLogContext()); - + search.execute(); return new SyncToken(maxChangeNumber[0]); @@ -197,15 +203,15 @@ public SyncToken getLatestSyncToken(ObjectClass oclass) { builder.setOption(LdapSearch.OP_IGNORE_BUILT_IN_FILTERS, true); builder.setOption(LdapConstants.SEARCH_FILTER_NAME, "(objectClass=changelogEntry)"); - Class searchStrategyClass = LdapSearchStrategy.getSearchStrategy(conn, builder.build()); + Class searchStrategyClass = LdapSearchStrategy.getSearchStrategy(conn, builder. + build()); switch (searchStrategyClass.getSimpleName()) { case "PagedSearchStrategy": if (conn.getConfiguration().getChangeLogPagingSupport()) { return getLatestSyncTokenPaged(oclass, builder); - } - else { - return getLatestSyncTokenDefault(oclass, builder); + } else { + return getLatestSyncTokenDefault(oclass, builder); } default: return getLatestSyncTokenDefault(oclass, builder); @@ -238,15 +244,18 @@ public void sync( final boolean[] results = new boolean[1]; ResultsHandler resultsHandler = new ResultsHandler() { + @Override public boolean handle(final ConnectorObject object) { results[0] = true; - - int changeNumber = convertToInt((String) object.getAttributeByName(changeNumberAttr).getValue().get(0), - -1); - if (changeNumber > currentChangeNumber[0]) { - currentChangeNumber[0] = changeNumber; + Attribute changeNumberAttr = object.getAttributeByName(getChangeNumberAttribute()); + int changeNumber = -1; + if (changeNumberAttr != null) { + changeNumber = convertToInt(AttributeUtil.getStringValue(changeNumberAttr), -1); + if (changeNumber > currentChangeNumber[0]) { + currentChangeNumber[0] = changeNumber; + } } SyncDelta delta; @@ -266,12 +275,14 @@ public boolean handle(final ConnectorObject object) { do { results[0] = false; - builder.setOption(LdapConstants.SEARCH_FILTER_NAME, getChangeLogSearchFilter(changeNumberAttr, currentChangeNumber[0])); + builder.setOption( + LdapConstants.SEARCH_FILTER_NAME, + getChangeLogSearchFilter(changeNumberAttr, currentChangeNumber[0])); - LdapSearch search = new LdapSearch(conn, - oclass, - null, - resultsHandler, + LdapSearch search = new LdapSearch(conn, + oclass, + null, + resultsHandler, builder.build(), conn.getConfiguration().getChangeLogContext()); @@ -328,14 +339,12 @@ protected SyncDelta createSyncDelta( final Map> attrChanges = getAttributeChanges(changeType, changes); if (filterOutByModifiersNames(attrChanges)) { - LOG.ok("Skipping entry because modifiersName is in the list of " - + "modifiersName's to filter out"); + LOG.ok("Skipping entry because modifiersName is in the list of modifiersName's to filter out"); return null; } if (filterOutByAttributes(attrChanges)) { - LOG.ok("Skipping entry because no changed attributes in the list " - + "of attributes to synchronize"); + LOG.ok("Skipping entry because no changed attributes in the list of attributes to synchronize"); return null; } @@ -449,7 +458,13 @@ protected SyncDelta createSyncDelta( return syncDeltaBuilder.build(); } - protected SyncDelta createDeletionSyncDelta(SyncDeltaBuilder syncDeltaBuilder, String targetDN, ObjectClass oclass, AttributesAccessor inputAttrs) throws InvalidNameException { + protected SyncDelta createDeletionSyncDelta( + final SyncDeltaBuilder syncDeltaBuilder, + final String targetDN, + final ObjectClass oclass, + final AttributesAccessor inputAttrs) + throws InvalidNameException { + LOG.ok("Creating sync delta for deleted entry {0}", targetDN); Uid deletedUid = new Uid(targetDN); @@ -498,8 +513,7 @@ protected boolean filterOutByBaseContexts(final LdapName targetName) { return !LdapUtil.isUnderContexts(targetName, baseContexts); } - protected boolean filterOutByModifiersNames( - final Map> changes) { + protected boolean filterOutByModifiersNames(final Map> changes) { Set filter = conn.getConfiguration(). getModifiersNamesToFilterOutAsLdapNames(); if (filter.isEmpty()) { @@ -515,8 +529,7 @@ protected boolean filterOutByModifiersNames( return filter.contains(modifiersName); } - protected boolean filterOutByAttributes( - final Map> attrChanges) { + protected boolean filterOutByAttributes(final Map> attrChanges) { Set filter = getAttributesToSynchronize(); if (filter.isEmpty()) { LOG.ok("Filtering by attributes disabled"); @@ -526,8 +539,7 @@ protected boolean filterOutByAttributes( return !containsAny(filter, changedAttrs); } - protected boolean filterOutByObjectClasses( - final List objectClasses) { + protected boolean filterOutByObjectClasses(final List objectClasses) { Set filter = getObjectClassesToSynchronize(); if (filter.isEmpty()) { LOG.ok("Filtering by object class disabled"); @@ -551,8 +563,7 @@ protected String getModifiedEntrySearchFilter(ObjectClass oclass) { } protected int getStartChangeNumber(final SyncToken lastToken) { - return lastToken != null ? (Integer) lastToken. - getValue() + 1 : 0; + return lastToken != null ? (Integer) lastToken.getValue() + 1 : 0; } protected Map> getAttributeChanges(final String changeType, final String ldif) { @@ -633,8 +644,7 @@ protected Object decodeAttributeValue(final NameValue nameValue) { } } - protected String getChangeLogSearchFilter( - final String changeNumberAttr, final int startChangeNumber) { + protected String getChangeLogSearchFilter(final String changeNumberAttr, final int startChangeNumber) { int blockSize = conn.getConfiguration().getChangeLogBlockSize(); boolean filterWithOrInsteadOfAnd = conn.getConfiguration(). isFilterWithOrInsteadOfAnd(); @@ -751,7 +761,7 @@ protected Uid createUid(final String uidAttr, final String targetDN) throws Inva return matchingRnd == null ? null : new Uid(matchingRnd.getValue().toString()); } - public static int convertToInt(String number, final int def) { + protected static int convertToInt(String number, final int def) { int result = def; if (number != null && number.length() > 0) { int decimal = number.indexOf('.'); diff --git a/src/main/java/net/tirasa/connid/bundles/ldap/sync/sunds/SunDSChangeLogSyncStrategy.java b/src/main/java/net/tirasa/connid/bundles/ldap/sync/sunds/SunDSChangeLogSyncStrategy.java index 316ebb6..c4f7dee 100644 --- a/src/main/java/net/tirasa/connid/bundles/ldap/sync/sunds/SunDSChangeLogSyncStrategy.java +++ b/src/main/java/net/tirasa/connid/bundles/ldap/sync/sunds/SunDSChangeLogSyncStrategy.java @@ -31,7 +31,6 @@ import net.tirasa.connid.bundles.ldap.LdapConnection; import net.tirasa.connid.bundles.ldap.commons.LdapUtil; import net.tirasa.connid.bundles.ldap.sync.GenericChangeLogSyncStrategy; -import org.identityconnectors.common.logging.Log; import org.identityconnectors.framework.common.exceptions.ConnectorException; import org.identityconnectors.framework.common.objects.Attribute; import org.identityconnectors.framework.common.objects.AttributesAccessor; @@ -48,9 +47,6 @@ */ public class SunDSChangeLogSyncStrategy extends GenericChangeLogSyncStrategy { - // TODO detect that the change log has been trimmed. - private static final Log LOG = Log.getLog(SunDSChangeLogSyncStrategy.class); - private ChangeLogAttributes changeLogAttrs; public SunDSChangeLogSyncStrategy(LdapConnection conn) { @@ -63,8 +59,13 @@ public SyncToken getLatestSyncToken(ObjectClass oclass) { } @Override - protected SyncDelta createDeletionSyncDelta(SyncDeltaBuilder syncDeltaBuilder, String targetDN, ObjectClass oclass, - AttributesAccessor inputAttrs) throws InvalidNameException { + protected SyncDelta createDeletionSyncDelta( + final SyncDeltaBuilder syncDeltaBuilder, + final String targetDN, + final ObjectClass oclass, + final AttributesAccessor inputAttrs) + throws InvalidNameException { + LOG.ok("Creating sync delta for deleted entry {0}", inputAttrs.findString("targetEntryUUID")); String uidAttr = conn.getSchema().getLdapUidAttribute(oclass);