Skip to content

Commit

Permalink
Add orphan node check
Browse files Browse the repository at this point in the history
Signed-off-by: yichen88 <tang.yichenyves@gmail.com>
  • Loading branch information
yichen88 committed May 26, 2021
1 parent c2df676 commit 155edac
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public class CassandraAppStorage extends AbstractAppStorage {

public static final String REF_NOT_FOUND = "REFERENCE_NOT_FOUND";

public static final String ORPHAN_NODE = "ORPHAN_NODE";

private final String fileSystemName;

private final Supplier<CassandraContext> contextSupplier;
Expand Down Expand Up @@ -1504,6 +1506,9 @@ public List<FileSystemCheckIssue> checkFileSystem(FileSystemCheckOptions options
case REF_NOT_FOUND:
checkReferenceNotFound(results, options);
break;
case ORPHAN_NODE:
checkOrphanNode(results, options);
break;
default:
LOGGER.warn("Check {} not supported in {}", type, getClass());
}
Expand All @@ -1512,6 +1517,37 @@ public List<FileSystemCheckIssue> checkFileSystem(FileSystemCheckOptions options
return results;
}

private void checkOrphanNode(List<FileSystemCheckIssue> results, FileSystemCheckOptions options) {
List<Statement> statements = new ArrayList<>();
// get all child id which parent name is null
ResultSet resultSet = getSession().execute(select(ID, CHILD_ID, NAME, CHILD_NAME).from(CHILDREN_BY_NAME_AND_CLASS));
for (Row row : resultSet) {
if (row.getString(NAME) == null) {
UUID nodeId = row.getUUID(CHILD_ID);
String nodeName = row.getString(CHILD_NAME);
UUID fakeParentId = row.getUUID(ID);
FileSystemCheckIssue issue = new FileSystemCheckIssue().setNodeId(nodeId.toString())
.setNodeName(nodeName)
.setType(ORPHAN_NODE)
.setDescription(nodeName + "(" + nodeId + ") is an orphan node. Its fake parent id:" + fakeParentId);
if (options.isRepair()) {
statements.add(delete().from(CHILDREN_BY_NAME_AND_CLASS)
.where(eq(ID, nodeId)));
statements.add(delete().from(CHILDREN_BY_NAME_AND_CLASS)
.where(eq(ID, fakeParentId)));
issue.setRepaired(true);
issue.setResolutionDescription("Delete row and its parent row");
}
results.add(issue);
}
}
if (options.isRepair()) {
for (Statement statement : statements) {
getSession().execute(statement);
}
}
}

private void checkReferenceNotFound(List<FileSystemCheckIssue> results, FileSystemCheckOptions options) {
List<Statement> statements = new ArrayList<>();
Set<ChildNodeInfo> notFoundIds = new HashSet<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
import static com.datastax.driver.core.querybuilder.QueryBuilder.insertInto;
import static com.powsybl.afs.cassandra.CassandraConstants.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.*;
import static org.junit.Assert.fail;
import static org.junit.Assert.*;

/**
Expand All @@ -48,6 +49,20 @@ protected void nextDependentTests() {
testSupportedChecks();
testInconsistendNodeRepair();
testAbsentChildRepair();
testOrphanNodeRepair();
}

private void testOrphanNodeRepair() {
NodeInfo orphanNode = storage.createNode(UUIDs.timeBased().toString(), "orphanNodes", FOLDER_PSEUDO_CLASS, "", 0, new NodeGenericMetadata());
assertThatThrownBy(() -> storage.getParentNode(orphanNode.getId())).isInstanceOf(NullPointerException.class);
FileSystemCheckOptions repairOption = new FileSystemCheckOptionsBuilder()
.addCheckTypes(CassandraAppStorage.ORPHAN_NODE)
.repair().build();
List<FileSystemCheckIssue> issues = storage.checkFileSystem(repairOption);
assertThat(issues).hasOnlyOneElementSatisfying(i -> assertEquals(orphanNode.getId(), i.getNodeId()));
assertThatThrownBy(() -> storage.getParentNode(orphanNode.getId()))
.isInstanceOf(CassandraAfsException.class)
.hasMessageContaining("not found");
}

void testInconsistendNodeRepair() {
Expand Down

0 comments on commit 155edac

Please sign in to comment.