Skip to content

Commit

Permalink
Fixed #585 by updating LogHandler to requery & update any potential c…
Browse files Browse the repository at this point in the history
…hild logs without the parent log set
  • Loading branch information
jongpie committed Jan 20, 2024
1 parent c1aeecd commit e28a397
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 1 deletion.
23 changes: 23 additions & 0 deletions nebula-logger/core/main/log-management/classes/LogHandler.cls
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public without sharing class LogHandler extends LoggerSObjectHandler {
protected override void executeAfterInsert(Map<Id, SObject> triggerNewMap) {
this.logs = (List<Log__c>) triggerNewMap.values();

this.updateUnlinkedChildLogs();
this.shareLogsWithLoggingUsers();
}

Expand Down Expand Up @@ -132,8 +133,14 @@ public without sharing class LogHandler extends LoggerSObjectHandler {
parentLogTransactionIdToRecordId.put(parentLog.TransactionId__c, parentLog.Id);
}

// List<Log__c> logsWithParentLog = new List<Log__c>();
// List<Log__c> logsWithParentTransactionId = new List<Log__c>();

for (Log__c log : this.logs) {
if (String.isNotBlank(log.ParentLogTransactionId__c)) {
// if (parentLogTransactionIdToRecordId.containsKey(log.ParentLogTransactionId__c) == false) {
// parentLogTransactionIdToRecordId.get(log.ParentLogTransactionId__c);
// }
log.ParentLog__c = parentLogTransactionIdToRecordId.get(log.ParentLogTransactionId__c);
}
}
Expand Down Expand Up @@ -196,6 +203,22 @@ public without sharing class LogHandler extends LoggerSObjectHandler {
}
}

private void updateUnlinkedChildLogs() {
Map<String, Log__c> transactionIdToPossibleParentLog = new Map<String, Log__c>();
for (Log__c log : this.logs) {
if (log.TransactionId__c != log.ParentLogTransactionId__c) {
transactionIdToPossibleParentLog.put(log.TransactionId__c, log);
}
}
List<String> possibleParentLogTransactionIds = new List<String>(transactionIdToPossibleParentLog.keySet());

List<Log__c> unlinkedChildLogs = LogManagementDataSelector.getInstance().getLogsWithoutParentLogByParentTransactionId(possibleParentLogTransactionIds);
for (Log__c unlinkedChildLog : unlinkedChildLogs) {
unlinkedChildLog.ParentLog__c = transactionIdToPossibleParentLog.get(unlinkedChildLog.ParentLogTransactionId__c)?.Id;
}
LoggerDataStore.getDatabase().updateRecords(unlinkedChildLogs);
}

private void shareLogsWithLoggingUsers() {
// For each log record, share the record with the user that created the log (Log__c.LoggedBy__c)
List<Log__Share> logShares = new List<Log__Share>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,19 @@ public without sharing virtual class LogManagementDataSelector {
return [SELECT Id, Name, LoggedBy__c, LoggedBy__r.Name, StartTime__c, TotalLogEntries__c, TransactionId__c FROM Log__c WHERE Id IN :logIds];
}

/**
* @description Returns a `List<Log__c>` of records with the specified parent transaction IDs and a `null` value in `ParentLog__c`
* @param transactionIds The list of `String` parent transaction IDs of the `Log__c` records to query
* @return The list of matching `Log__c` records
*/
public virtual List<Log__c> getLogsWithoutParentLogByParentTransactionId(List<String> parentTransactionIds) {
return [
SELECT Id, ParentLogTransactionId__c, ParentLog__c, ParentLog__r.TransactionId__c, TransactionId__c
FROM Log__c
WHERE ParentLogTransactionId__c IN :parentTransactionIds AND ParentLog__c = NULL
];
}

/**
* @description Returns a `List<Log__c>` of records with the specified transaction IDs
* @param transactionIds The list of `String` transaction IDs of the `Log__c` records to query
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ private class LogHandler_Tests {
}

@IsTest
static void it_should_set_parent_log_when_it_exists() {
static void it_should_set_parent_log_when_it_exists_in_the_database() {
String parentLogTransactionId = 'ABC-1234';
Log__c parentLog = new Log__c(TransactionId__c = parentLogTransactionId);
insert parentLog;
Expand All @@ -300,6 +300,33 @@ private class LogHandler_Tests {
System.Assert.areEqual(parentLog.Id, log.ParentLog__c, JSON.serializePretty(log));
}

@IsTest
static void it_should_set_parent_log_when_it_is_created_after_child_log() {
String parentLogTransactionId = 'ABC-1234';
Log__c log = new Log__c(ParentLogTransactionId__c = parentLogTransactionId, TransactionId__c = 'XYZ-5678');
insert log;
Log__c parentLog = new Log__c(TransactionId__c = parentLogTransactionId);

insert parentLog;

log = [SELECT Id, ParentLogTransactionId__c, ParentLog__c FROM Log__c WHERE Id = :log.Id];
System.Assert.areEqual(parentLogTransactionId, log.ParentLogTransactionId__c, JSON.serializePretty(log));
System.Assert.areEqual(parentLog.Id, log.ParentLog__c, JSON.serializePretty(log));
}

@IsTest
static void it_should_set_parent_log_when_it_exists_in_the_same_trigger_context() {
String parentLogTransactionId = 'ABC-1234';
Log__c parentLog = new Log__c(TransactionId__c = parentLogTransactionId);
Log__c log = new Log__c(ParentLogTransactionId__c = parentLogTransactionId, TransactionId__c = 'XYZ-5678');

insert new List<Log__c>{ log, parentLog };

log = [SELECT Id, ParentLogTransactionId__c, ParentLog__c FROM Log__c WHERE Id = :log.Id];
System.Assert.areEqual(parentLogTransactionId, log.ParentLogTransactionId__c, JSON.serializePretty(log));
System.Assert.areEqual(parentLog.Id, log.ParentLog__c, JSON.serializePretty(log));
}

@IsTest
static void it_should_keep_existing_retention_details_when_populated() {
setupConfigurations();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,44 @@ private class LogManagementDataSelector_Tests {
System.Assert.areEqual(logs.size(), returnedResults.size());
}

@IsTest
static void it_returns_logs_for_specified_parent_log_transaction_ids_and_no_parent_log() {
LoggerSObjectHandler.shouldExecute(false);
Log__c parentLog = (Log__c) LoggerMockDataCreator.createDataBuilder(Schema.Log__c.SObjectType).populateRequiredFields().getRecord();
parentLog.TransactionId__c = 'some unique value for this log';
insert parentLog;
List<Log__c> logsToCreate = new List<Log__c>();
List<Log__c> expectedLogs = new List<Log__c>();
List<String> parentLogTransactionIds = new List<String>();
for (Integer i = 0; i < 5; i++) {
Log__c log = (Log__c) LoggerMockDataCreator.createDataBuilder(Schema.Log__c.SObjectType).populateRequiredFields().getRecord();
log.TransactionId__c = 'some_fake_transaction_id_' + i;
// Make 1 log with an actual an actual parent log
if (i == 0) {
log.ParentLog__c = parentLog.Id;
log.ParentLogTransactionId__c = parentLog.TransactionId__c;
}
// Make a few logs with a parent transaction ID but no parent log
if (i == 1 || i == 2 || i == 3) {
log.ParentLog__c = null;
log.ParentLogTransactionId__c = 'some other value';
expectedLogs.add(log);
}
if (String.isNotBlank(log.ParentLogTransactionId__c)) {
parentLogTransactionIds.add(log.ParentLogTransactionId__c);
}
logsToCreate.add(log);
}
System.Assert.areEqual(parentLogTransactionIds.size(), expectedLogs.size() + 1, 'Test has started under the wrong conditions');
insert logsToCreate;

List<Log__c> returnedResults = LogManagementDataSelector.getInstance().getLogsWithoutParentLogByParentTransactionId(parentLogTransactionIds);

System.Assert.isFalse(returnedResults.isEmpty());
System.Assert.areEqual(expectedLogs.size(), returnedResults.size());
System.Assert.areEqual(new Map<Id, Log__c>(expectedLogs).keySet(), new Map<Id, Log__c>(returnedResults).keySet());
}

@IsTest
static void it_returns_logs_for_specified_log_transaction_ids() {
LoggerSObjectHandler.shouldExecute(false);
Expand Down

0 comments on commit e28a397

Please sign in to comment.