7212N/A * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
7212N/A * file and include the License file at legal-notices/CDDLv1_0.txt.
7263N/Aimport static org.opends.server.replication.server.changelog.api.DBCursor.KeyMatchingStrategy.*;
7251N/Aimport static org.opends.server.replication.server.changelog.api.DBCursor.PositionStrategy.*;
7257N/A private static final String ENTRY_SENDER_ATTACHMENT = OID_ECL_COOKIE_EXCHANGE_CONTROL + ".entrySender";
7237N/A CHANGELOG_ROOT_OBJECT_CLASSES.put(DirectoryServer.getObjectClass("container", true), "container");
7237N/A CHANGELOG_ENTRY_OBJECT_CLASSES.put(DirectoryServer.getObjectClass(OC_CHANGELOG_ENTRY, true), OC_CHANGELOG_ENTRY);
7244N/A catch (DirectoryException e)
7244N/A throw new RuntimeException(e);
7237N/A private final Set<String> supportedControls = Collections.singleton(OID_ECL_COOKIE_EXCHANGE_CONTROL);
7237N/A public ChangelogBackend(final ReplicationServer replicationServer, final ECLEnabledDomainPredicate domainPredicate)
7237N/A setPrivateBackend(true);
7237N/A catch (final DirectoryException e)
7218N/A throw new InitializationException(
7251N/A ERR_BACKEND_CANNOT_REGISTER_BASEDN.get(DN_EXTERNAL_CHANGELOG_ROOT, getExceptionMessage(e)), e);
7244N/A super.finalizeBackend();
7237N/A catch (final DirectoryException e)
7218N/A if (debugEnabled())
7263N/A new MultiDomainServerState(), GREATER_THAN_OR_EQUAL_TO_KEY, ON_MATCHING_KEY, getExcludedBaseDNs());
7251N/A catch (ChangelogException e)
7251N/A throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, ERR_CHANGELOG_BACKEND_ATTRIBUTE.get(
7251N/A return baseEntryHasSubordinates;
7237N/A public long numSubordinates(final DN entryDN, final boolean subtree) throws DirectoryException
7251N/A * It is executed multiple times per persistent search, multi-threaded, until the persistent search is cancelled.
7257N/A public void notifyCookieEntryAdded(DN baseDN, UpdateMsg updateMsg) throws ChangelogException
7257N/A catch (DirectoryException e)
7257N/A * Notifies persistent searches of this backend that a new change number entry was added to it.
7257N/A * It is executed multiple times per persistent search, multi-threaded, until the persistent search is cancelled.
7257N/A public void notifyChangeNumberEntryAdded(DN baseDN, long changeNumber, String cookieString, UpdateMsg updateMsg)
7244N/A throws ChangelogException
7257N/A final Entry changeNumberEntry = createEntryFromMsg(baseDN, changeNumber, cookieString, updateMsg);
7257N/A final ChangeNumberEntrySender entrySender = searchOp.getAttachment(ENTRY_SENDER_ATTACHMENT);
7244N/A catch (DirectoryException e)
7237N/A catch (ChangelogException e)
7237N/A throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, ERR_CHANGELOG_BACKEND_SEARCH.get(
7243N/A private SearchParams buildSearchParameters(final SearchOperation searchOperation) throws DirectoryException
7218N/A return supportedControls;
7212N/A throws DirectoryException
7212N/A throws DirectoryException
7237N/A public void removeBackup(BackupDirectory backupDirectory, String backupID) throws DirectoryException
7237N/A catch (DirectoryException e)
7237N/A if (debugEnabled())
7237N/A return lowestChangeNumber;
7237N/A return highestChangeNumber;
7251N/A return excludedBaseDNs;
7251N/A return excludedDNs;
7237N/A void optimizeSearchParameters(final SearchParams params, final DN baseDN, final SearchFilter userFilter)
7237N/A throws DirectoryException
7237N/A final SearchParams optimized = optimizeSearchUsingFilter(equalityFilter != null ? equalityFilter : userFilter);
7237N/A private SearchFilter buildSearchFilterFrom(final DN baseDN, final String lowerCaseAttr, final String upperCaseAttr)
7237N/A private SearchParams optimizeSearchUsingFilter(final SearchFilter filter) throws DirectoryException
7237N/A throws DirectoryException
7237N/A catch (NumberFormatException e)
7237N/A Message.raw("Could not convert value '%s' to long", assertionValue.getNormalizedValue().toString()));
7251N/A private void initialSearch(final SearchParams searchParams, final SearchOperation searchOperation)
7251N/A private void initialSearchFromCookie(final SearchParams searchParams, final SearchOperation searchOperation)
7270N/A searchParams.cookie, GREATER_THAN_OR_EQUAL_TO_KEY, AFTER_MATCHING_KEY, searchParams.getExcludedBaseDNs());
7270N/A final boolean continueSearch = sendCookieEntriesFromCursor(entrySender, replicaUpdatesCursor);
7257N/A if (continueSearch)
7270N/A final ECLMultiDomainDBCursor replicaUpdatesCursor) throws ChangelogException, DirectoryException
7257N/A boolean continueSearch = true;
7257N/A return continueSearch;
7270N/A private void validatePersistentSearch(final PersistentSearch pSearch) throws DirectoryException
7270N/A final SearchPhase startPhase = pSearch.isChangesOnly() ? SearchPhase.PERSISTENT : SearchPhase.INITIAL;
7270N/A searchOp.setAttachment(ENTRY_SENDER_ATTACHMENT, new ChangeNumberEntrySender(searchOp, startPhase));
7244N/A final ServerState state = getChangelogDB().getReplicationDomainDB().getDomainNewestCSNs(baseDN);
7237N/A private void validateProvidedCookie(final SearchParams searchParams) throws DirectoryException
7251N/A private void initialSearchFromChangeNumber(final SearchParams params, final SearchOperation searchOperation)
7257N/A final AtomicReference<MultiDomainDBCursor> replicaUpdatesCursor = new AtomicReference<MultiDomainDBCursor>();
7257N/A final boolean continueSearch =
7263N/A sendChangeNumberEntriesFromCursors(entrySender, params, cnIndexDBCursor, replicaUpdatesCursor, cookie);
7257N/A if (continueSearch)
7263N/A sendChangeNumberEntriesFromCursors(entrySender, params, cnIndexDBCursor, replicaUpdatesCursor, cookie);
7257N/A private boolean sendChangeNumberEntriesFromCursors(final ChangeNumberEntrySender entrySender,
7257N/A boolean continueSearch = true;
7257N/A if (continueSearch)
7257N/A final UpdateMsg updateMsg = findReplicaUpdateMessage(cnIndexRecord, replicaUpdatesCursor.get());
7257N/A return continueSearch;
7263N/A MultiDomainServerState cookie, final ChangeNumberIndexRecord cnIndexRecord) throws ChangelogException
7263N/A getChangelogDB().getReplicationDomainDB().getCursorFrom(state, GREATER_THAN_OR_EQUAL_TO_KEY, ON_MATCHING_KEY);
7237N/A return replicaUpdatesCursor;
7237N/A "No more replica update messages with a csn newer than " + updateMsg.getCSN() + " exist."));
7237N/A changeNumberToUse = oldestRecord == null ? CHANGE_NUMBER_FOR_EMPTY_CURSOR : oldestRecord.getChangeNumber();
7257N/A private static Entry createEntryFromMsg(final DN baseDN, final long changeNumber, final String cookie,
7237N/A return createChangelogEntry(baseDN, changeNumber, cookie, delMsg, null, "delete", delMsg.getInitiatorsName());
7237N/A Message.raw("Unexpected message type when trying to create changelog entry for dn %s : %s", baseDN.toString(),
7257N/A private static Entry createAddMsg(final DN baseDN, final long changeNumber, final String cookie, final UpdateMsg msg)
7237N/A throws DirectoryException
7237N/A return createChangelogEntry(baseDN, changeNumber, cookie, addMsg, ldifChanges, "add", changeInitiatorsName);
7257N/A private static Entry createModifyMsg(final DN baseDN, final long changeNumber, final String cookie,
7237N/A final Entry entry = createChangelogEntry(baseDN, changeNumber, cookie, modifyMsg, ldifChanges,
7237N/A if (isModifyDNMsg)
7257N/A private static void logEncodingMessageError(String messageType, DN entryDN, Exception exception)
7237N/A "An exception was encountered while trying to encode a replication " + messageType + " message for entry \""
7243N/A private void checkChangelogReadPrivilege(SearchOperation searchOp) throws DirectoryException
7237N/A private static Entry createChangelogEntry(final DN baseDN, final long changeNumber, final String cookie,
7237N/A final Map<AttributeType, List<Attribute>> userAttrs = new LinkedHashMap<AttributeType, List<Attribute>>();
7237N/A final Map<AttributeType, List<Attribute>> opAttrs = new LinkedHashMap<AttributeType, List<Attribute>>();
7237N/A addAttributeByType("changenumber", "changeNumber", String.valueOf(changeNumber), userAttrs, opAttrs);
7237N/A addAttributeByType("replicaidentifier", "replicaIdentifier", Integer.toString(csn.getServerId()),
7237N/A addAttributeByType("changeinitiatorsname", "changeInitiatorsName", changeInitiatorsName, userAttrs, opAttrs);
7237N/A addAttributeByType("includedattributes", "includedAttributes", includedAttributesLDIF, userAttrs, opAttrs);
7251N/A * It will also send the base changelog entry if it needs to be sent and was not sent before.
7257N/A private static boolean sendEntryIfMatches(SearchOperation searchOp, Entry entry, String cookie)
7257N/A throws DirectoryException
7257N/A private static boolean matchBaseAndScopeAndFilter(SearchOperation searchOp, Entry entry) throws DirectoryException
7251N/A final Map<AttributeType, List<Attribute>> userAttrs = new LinkedHashMap<AttributeType, List<Attribute>>();
7251N/A final Map<AttributeType, List<Attribute>> operationalAttrs = new LinkedHashMap<AttributeType, List<Attribute>>();
7251N/A // -- then we risk returning more entries if new entries come in after we computed numSubordinates
7251N/A // - Or we accumulate all the entries that must be returned before sending them => OutOfMemoryError
7251N/A addAttributeByUppercaseName(ATTR_COMMON_NAME, ATTR_COMMON_NAME, BACKEND_ID, userAttrs, operationalAttrs);
7251N/A addAttributeByUppercaseName("hassubordinates", "hasSubordinates", hasSubordinatesStr, userAttrs, operationalAttrs);
7251N/A addAttributeByUppercaseName("entrydn", "entryDN", DN_EXTERNAL_CHANGELOG_ROOT, userAttrs, operationalAttrs);
7251N/A return new Entry(CHANGELOG_BASE_DN, CHANGELOG_ROOT_OBJECT_CLASSES, userAttrs, operationalAttrs);
7237N/A private static void addAttribute(final Entry e, final String attrType, final String attrValue)
7237N/A addAttribute(attrNameLowercase, attrNameUppercase, attrValue, userAttrs, operationalAttrs, true);
7237N/A addAttribute(attrNameLowercase, attrNameUppercase, attrValue, userAttrs, operationalAttrs, false);
7257N/A private final AtomicReference<SearchPhase> searchPhase = new AtomicReference<SearchPhase>(SearchPhase.INITIAL);
7257N/A synchronized (transitioningLock)
7257N/A switch (stateValue)
7257N/A case TRANSITIONING:
7257N/A synchronized (transitioningLock)
7257N/A catch (InterruptedException e)
7257N/A case PERSISTENT:
7263N/A private boolean initialSearchSendEntry(ChangeNumberIndexRecord cnIndexRecord, UpdateMsg updateMsg,
7263N/A final Entry entry = createEntryFromMsg(baseDN, cnIndexRecord.getChangeNumber(), cookie.toString(), updateMsg);
7257N/A private void persistentSearchSendEntry(long changeNumber, Entry entry) throws DirectoryException
7257N/A private final ConcurrentSkipListMap<Pair<DN, Integer>, SendEntryData<CSN>> replicaIdToSendEntryData =
7270N/A private boolean initialSearchSendEntry(final UpdateMsg updateMsg, final DN baseDN) throws DirectoryException
7257N/A throws DirectoryException