use of com.unboundid.ldif.LDIFModifyDNChangeRecord in project ldapsdk by pingidentity.
the class ScrambleAttributeTransformation method transformChangeRecord.
/**
* {@inheritDoc}
*/
@Override()
@Nullable()
public LDIFChangeRecord transformChangeRecord(@NotNull final LDIFChangeRecord r) {
if (r == null) {
return null;
}
// entry.
if (r instanceof LDIFAddChangeRecord) {
final LDIFAddChangeRecord addRecord = (LDIFAddChangeRecord) r;
return new LDIFAddChangeRecord(transformEntry(addRecord.getEntryToAdd()), addRecord.getControls());
}
// If it's a delete change record, then see if we need to scramble the DN.
if (r instanceof LDIFDeleteChangeRecord) {
if (scrambleEntryDNs) {
return new LDIFDeleteChangeRecord(scrambleDN(r.getDN()), r.getControls());
} else {
return r;
}
}
// modification values.
if (r instanceof LDIFModifyChangeRecord) {
final LDIFModifyChangeRecord modifyRecord = (LDIFModifyChangeRecord) r;
final Modification[] originalMods = modifyRecord.getModifications();
final Modification[] newMods = new Modification[originalMods.length];
for (int i = 0; i < originalMods.length; i++) {
// If the modification doesn't have any values, then just use the
// original modification.
final Modification m = originalMods[i];
if (!m.hasValue()) {
newMods[i] = m;
continue;
}
// See if the modification targets an attribute that we should scramble.
// If not, then just use the original modification.
final String attrName = StaticUtils.toLowerCase(Attribute.getBaseName(m.getAttributeName()));
if (!attributes.containsKey(attrName)) {
newMods[i] = m;
continue;
}
// Scramble the values just like we do for an attribute.
final Attribute scrambledAttribute = scrambleAttribute(m.getAttribute());
newMods[i] = new Modification(m.getModificationType(), m.getAttributeName(), scrambledAttribute.getRawValues());
}
if (scrambleEntryDNs) {
return new LDIFModifyChangeRecord(scrambleDN(modifyRecord.getDN()), newMods, modifyRecord.getControls());
} else {
return new LDIFModifyChangeRecord(modifyRecord.getDN(), newMods, modifyRecord.getControls());
}
}
// of the components.
if (r instanceof LDIFModifyDNChangeRecord) {
if (scrambleEntryDNs) {
final LDIFModifyDNChangeRecord modDNRecord = (LDIFModifyDNChangeRecord) r;
return new LDIFModifyDNChangeRecord(scrambleDN(modDNRecord.getDN()), scrambleDN(modDNRecord.getNewRDN()), modDNRecord.deleteOldRDN(), scrambleDN(modDNRecord.getNewSuperiorDN()), modDNRecord.getControls());
} else {
return r;
}
}
// This should never happen.
return r;
}
use of com.unboundid.ldif.LDIFModifyDNChangeRecord in project ldapsdk by pingidentity.
the class RedactAttributeTransformation method transformChangeRecord.
/**
* {@inheritDoc}
*/
@Override()
@Nullable()
public LDIFChangeRecord transformChangeRecord(@NotNull final LDIFChangeRecord r) {
if (r == null) {
return null;
}
// entry.
if (r instanceof LDIFAddChangeRecord) {
final LDIFAddChangeRecord addRecord = (LDIFAddChangeRecord) r;
return new LDIFAddChangeRecord(transformEntry(addRecord.getEntryToAdd()), addRecord.getControls());
}
// that we might need to redact.
if (r instanceof LDIFDeleteChangeRecord) {
if (redactDNAttributes) {
final LDIFDeleteChangeRecord deleteRecord = (LDIFDeleteChangeRecord) r;
return new LDIFDeleteChangeRecord(redactDN(deleteRecord.getDN()), deleteRecord.getControls());
} else {
return r;
}
}
// If it's a modify change record, then redact all appropriate values.
if (r instanceof LDIFModifyChangeRecord) {
final LDIFModifyChangeRecord modifyRecord = (LDIFModifyChangeRecord) r;
final String newDN;
if (redactDNAttributes) {
newDN = redactDN(modifyRecord.getDN());
} else {
newDN = modifyRecord.getDN();
}
final Modification[] originalMods = modifyRecord.getModifications();
final Modification[] newMods = new Modification[originalMods.length];
for (int i = 0; i < originalMods.length; i++) {
// If the modification doesn't have any values, then just use the
// original modification.
final Modification m = originalMods[i];
if (!m.hasValue()) {
newMods[i] = m;
continue;
}
// See if the modification targets an attribute that we should redact.
// If not, then see if the attribute has a DN syntax.
final String attrName = StaticUtils.toLowerCase(Attribute.getBaseName(m.getAttributeName()));
if (!attributes.contains(attrName)) {
if (redactDNAttributes && (schema != null) && (MatchingRule.selectEqualityMatchingRule(attrName, schema) instanceof DistinguishedNameMatchingRule)) {
final String[] originalValues = m.getValues();
final String[] newValues = new String[originalValues.length];
for (int j = 0; j < originalValues.length; j++) {
newValues[j] = redactDN(originalValues[j]);
}
newMods[i] = new Modification(m.getModificationType(), m.getAttributeName(), newValues);
} else {
newMods[i] = m;
}
continue;
}
// Get the original values. If there's only one of them, or if we
// shouldn't preserve the original number of values, then just create a
// modification with a single value. Otherwise, create a modification
// with the appropriate number of values.
final ASN1OctetString[] originalValues = m.getRawValues();
if (preserveValueCount && (originalValues.length > 1)) {
final ASN1OctetString[] newValues = new ASN1OctetString[originalValues.length];
for (int j = 0; j < originalValues.length; j++) {
newValues[j] = new ASN1OctetString("***REDACTED" + (j + 1) + "***");
}
newMods[i] = new Modification(m.getModificationType(), m.getAttributeName(), newValues);
} else {
newMods[i] = new Modification(m.getModificationType(), m.getAttributeName(), "***REDACTED***");
}
}
return new LDIFModifyChangeRecord(newDN, newMods, modifyRecord.getControls());
}
// superior DN contain anything that we might need to redact.
if (r instanceof LDIFModifyDNChangeRecord) {
if (redactDNAttributes) {
final LDIFModifyDNChangeRecord modDNRecord = (LDIFModifyDNChangeRecord) r;
return new LDIFModifyDNChangeRecord(redactDN(modDNRecord.getDN()), redactDN(modDNRecord.getNewRDN()), modDNRecord.deleteOldRDN(), redactDN(modDNRecord.getNewSuperiorDN()), modDNRecord.getControls());
} else {
return r;
}
}
// We should never get here.
return r;
}
use of com.unboundid.ldif.LDIFModifyDNChangeRecord in project ldapsdk by pingidentity.
the class AuditLogReader method read.
/**
* Reads the next audit log message from the log file.
*
* @return The audit log message read from the log file, or {@code null} if
* there are no more messages to be read.
*
* @throws IOException If an error occurs while trying to read from the
* file.
*
* @throws AuditLogException If an error occurs while trying to parse the
* log message.
*/
@Nullable()
public AuditLogMessage read() throws IOException, AuditLogException {
// Read a list of lines until we find the end of the file or a blank line
// after a series of non-blank lines.
final List<String> fullMessageLines = new ArrayList<>(20);
final List<String> nonCommentLines = new ArrayList<>(20);
while (true) {
final String line = reader.readLine();
if (line == null) {
// more.
break;
}
if (line.isEmpty()) {
if (nonCommentLines.isEmpty()) {
// This means that we encountered consecutive blank lines, or blank
// lines with only comments between them. This is okay. We'll just
// clear the list of full message lines and keep reading.
fullMessageLines.clear();
continue;
} else {
// we read as an audit log message.
break;
}
} else {
// We read a non-empty line. Add it to the list of full message lines,
// and if it's not a comment, then add it to the list of non-comment
// lines.
fullMessageLines.add(line);
if (!line.startsWith("#")) {
nonCommentLines.add(line);
}
}
}
// end of the file.
if (nonCommentLines.isEmpty()) {
return null;
}
// Try to parse the set of non-comment lines as an LDIF change record. If
// that fails, then throw a log exception.
final LDIFChangeRecord changeRecord;
try {
final String[] ldifLines = StaticUtils.toArray(nonCommentLines, String.class);
changeRecord = LDIFReader.decodeChangeRecord(ldifLines);
} catch (final Exception e) {
Debug.debugException(e);
final String concatenatedLogLines = StaticUtils.concatenateStrings("[ ", "\"", ", ", "\"", " ]", fullMessageLines);
throw new AuditLogException(fullMessageLines, ERR_AUDIT_LOG_READER_CANNOT_PARSE_CHANGE_RECORD.get(concatenatedLogLines, StaticUtils.getExceptionMessage(e)), e);
}
// record.
if (changeRecord instanceof LDIFAddChangeRecord) {
return new AddAuditLogMessage(fullMessageLines, (LDIFAddChangeRecord) changeRecord);
} else if (changeRecord instanceof LDIFDeleteChangeRecord) {
return new DeleteAuditLogMessage(fullMessageLines, (LDIFDeleteChangeRecord) changeRecord);
} else if (changeRecord instanceof LDIFModifyChangeRecord) {
return new ModifyAuditLogMessage(fullMessageLines, (LDIFModifyChangeRecord) changeRecord);
} else if (changeRecord instanceof LDIFModifyDNChangeRecord) {
return new ModifyDNAuditLogMessage(fullMessageLines, (LDIFModifyDNChangeRecord) changeRecord);
} else {
// This should never happen.
final String concatenatedLogLines = StaticUtils.concatenateStrings("[ ", "\"", ", ", "\"", " ]", fullMessageLines);
throw new AuditLogException(fullMessageLines, ERR_AUDIT_LOG_READER_UNSUPPORTED_CHANGE_RECORD.get(concatenatedLogLines, changeRecord.getChangeType().getName()));
}
}
use of com.unboundid.ldif.LDIFModifyDNChangeRecord in project ldapsdk by pingidentity.
the class ParallelUpdateOperationQueue method getChangeRecord.
/**
* Retrieves the next LDIF change record to be processed. This method will
* block if the queue is currently empty but the end of the LDIF file has not
* yet been reached, or if all of the operations currently held in the queue
* are dependent upon an operation in progress.
*
* @param completedDNs The DNs of the entries targeted by the last change.
* It should be empty for the first request processed by
* a thread, should have a single element if the last
* change was an add, delete, or modify, and should have
* two elements if the last change was a modify DN.
*
* @return The next LDIF change record to be processed, or {@code null} if
* there are no more change records to process and the end of the
* LDIF file has been reached.
*/
@Nullable()
LDIFChangeRecord getChangeRecord(@NotNull final DN... completedDNs) {
synchronized (queueLock) {
for (final DN dn : completedDNs) {
activeChanges.remove(dn);
}
while (!(endOfLDIF && opQueue.isEmpty())) {
if (opQueue.isEmpty()) {
try {
queueLock.wait(1000L);
} catch (final InterruptedException e) {
Debug.debugException(e);
}
continue;
}
final Iterator<LDIFChangeRecord> iterator = opQueue.iterator();
iteratorLoop: while (iterator.hasNext()) {
final LDIFChangeRecord r = iterator.next();
// Get the parsed target DN for the change record.
final DN targetDN;
try {
targetDN = r.getParsedDN();
} catch (final LDAPException e) {
// This should never happen, but if it does then reject the change.
parallelUpdate.reject(r, e);
iterator.remove();
size--;
continue;
}
// conflict with any active operations.
if (!activeChanges.isEmpty()) {
for (final DN activeDN : activeChanges) {
if (activeDN.isAncestorOf(targetDN, true)) {
continue iteratorLoop;
}
}
if (r instanceof LDIFDeleteChangeRecord) {
for (final DN activeDN : activeChanges) {
if (activeDN.isDescendantOf(targetDN, false)) {
continue iteratorLoop;
}
}
} else if (r instanceof LDIFModifyDNChangeRecord) {
final LDIFModifyDNChangeRecord modDNRecord = (LDIFModifyDNChangeRecord) r;
final DN newDN;
try {
newDN = modDNRecord.getNewDN();
} catch (final LDAPException e) {
// We could not parse the new DN, so reject the change.
parallelUpdate.reject(r, e);
iterator.remove();
size--;
continue iteratorLoop;
}
for (final DN activeDN : activeChanges) {
if (activeDN.isDescendantOf(targetDN, false) || activeDN.isAncestorOf(newDN, true) || activeDN.isDescendantOf(newDN, false)) {
continue iteratorLoop;
}
}
// At this point, we know that the modify DN will be processed so
// reserve the new DN as well. The target DN will be reserved
// below.
activeChanges.add(newDN);
}
}
// At this point, the change will be processed so remove it from the
// queue and add it to the list of active changes. Also, notify any
// threads that might be waiting on the queue lock in case
// addChangeRecord is waiting on available space.
activeChanges.add(targetDN);
iterator.remove();
size--;
queueLock.notifyAll();
return r;
}
// complete before trying again.
try {
queueLock.wait(1000L);
} catch (final InterruptedException e) {
Debug.debugException(e);
}
}
}
// If we've gotten here, then there is no more data to be processed.
return null;
}
use of com.unboundid.ldif.LDIFModifyDNChangeRecord in project ldapsdk by pingidentity.
the class ParallelUpdateOperationThread method run.
/**
* Operates in a loop, retrieving changes from the operation queue and
* processing them.
*/
@Override()
public void run() {
LDIFChangeRecord r = opQueue.getChangeRecord();
// Various controls that might be present on the requests.
final Control undeleteRequestControl = new UndeleteRequestControl();
while (r != null) {
if (rateLimiter != null) {
rateLimiter.await();
}
DN parsedDN = null;
DN parsedNewDN = null;
final long startTime = System.currentTimeMillis();
try {
parsedDN = r.getParsedDN();
if (r instanceof LDIFAddChangeRecord) {
final AddRequest addRequest = ((LDIFAddChangeRecord) r).toAddRequest();
addRequest.addControls(addControls);
if (allowUndelete && addRequest.hasAttribute(ATTR_UNDELETE_FROM_DN)) {
addRequest.addControl(undeleteRequestControl);
}
connectionPool.add(addRequest);
parallelUpdate.opCompletedSuccessfully(r, (System.currentTimeMillis() - startTime));
} else if (r instanceof LDIFDeleteChangeRecord) {
final DeleteRequest deleteRequest = ((LDIFDeleteChangeRecord) r).toDeleteRequest();
deleteRequest.addControls(deleteControls);
connectionPool.delete(deleteRequest);
parallelUpdate.opCompletedSuccessfully(r, (System.currentTimeMillis() - startTime));
} else if (r instanceof LDIFModifyChangeRecord) {
final ModifyRequest modifyRequest = ((LDIFModifyChangeRecord) r).toModifyRequest();
modifyRequest.addControls(modifyControls);
connectionPool.modify(modifyRequest);
parallelUpdate.opCompletedSuccessfully(r, (System.currentTimeMillis() - startTime));
} else if (r instanceof LDIFModifyDNChangeRecord) {
final LDIFModifyDNChangeRecord modifyDNChangeRecord = (LDIFModifyDNChangeRecord) r;
parsedNewDN = modifyDNChangeRecord.getNewDN();
final ModifyDNRequest modifyDNRequest = modifyDNChangeRecord.toModifyDNRequest();
modifyDNRequest.addControls(modifyDNControls);
connectionPool.modifyDN(modifyDNRequest);
parallelUpdate.opCompletedSuccessfully(r, (System.currentTimeMillis() - startTime));
} else {
// This should never happen.
r.processChange(connectionPool);
parallelUpdate.opCompletedSuccessfully(r, (System.currentTimeMillis() - startTime));
}
} catch (final LDAPException e) {
Debug.debugException(e);
parallelUpdate.opFailed(r, e, (System.currentTimeMillis() - startTime));
}
if (parsedNewDN == null) {
r = opQueue.getChangeRecord(parsedDN);
} else {
r = opQueue.getChangeRecord(parsedDN, parsedNewDN);
}
}
}
Aggregations