This is an automated email from the ASF dual-hosted git repository.

adoroszlai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/master by this push:
     new 47525b297a HDDS-12050. Implement TransactionInfoRepair command for SCM 
(#7689)
47525b297a is described below

commit 47525b297aadfd4810fc818790fe6dab0b5206fe
Author: Sarveksha Yeshavantha Raju 
<[email protected]>
AuthorDate: Thu Jan 23 23:23:52 2025 +0530

    HDDS-12050. Implement TransactionInfoRepair command for SCM (#7689)
---
 .../repair/{om => }/TransactionInfoRepair.java     | 48 +++++++++++++++------
 .../apache/hadoop/ozone/repair/om/OMRepair.java    |  1 +
 .../apache/hadoop/ozone/repair/scm/SCMRepair.java  |  2 +
 .../repair/{om => }/TestTransactionInfoRepair.java | 49 +++++++++++++---------
 4 files changed, 69 insertions(+), 31 deletions(-)

diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/om/TransactionInfoRepair.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/TransactionInfoRepair.java
similarity index 72%
rename from 
hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/om/TransactionInfoRepair.java
rename to 
hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/TransactionInfoRepair.java
index ca66440720..4fca8e40a0 100644
--- 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/om/TransactionInfoRepair.java
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/TransactionInfoRepair.java
@@ -19,15 +19,17 @@
  * permissions and
  * limitations under the License.
  */
-package org.apache.hadoop.ozone.repair.om;
+package org.apache.hadoop.ozone.repair;
 
 import org.apache.hadoop.hdds.cli.HddsVersionProvider;
+import org.apache.hadoop.hdds.scm.metadata.SCMDBDefinition;
 import org.apache.hadoop.hdds.utils.IOUtils;
 import org.apache.hadoop.hdds.utils.TransactionInfo;
+import org.apache.hadoop.hdds.utils.db.DBColumnFamilyDefinition;
 import org.apache.hadoop.hdds.utils.db.StringCodec;
 import org.apache.hadoop.hdds.utils.db.managed.ManagedRocksDB;
 import org.apache.hadoop.ozone.debug.RocksDBUtils;
-import org.apache.hadoop.ozone.repair.RepairTool;
+import org.apache.hadoop.ozone.om.codec.OMDBDefinition;
 import org.rocksdb.ColumnFamilyDescriptor;
 import org.rocksdb.ColumnFamilyHandle;
 import org.rocksdb.RocksDBException;
@@ -38,14 +40,13 @@
 import java.util.List;
 
 import static org.apache.hadoop.ozone.OzoneConsts.TRANSACTION_INFO_KEY;
-import static 
org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TRANSACTION_INFO_TABLE;
 
 /**
- * Tool to update the highest term-index in transactionInfoTable.
+ * Tool to update the highest term-index in transaction info table.
  */
 @CommandLine.Command(
     name = "update-transaction",
-    description = "CLI to update the highest index in transactionInfoTable. 
Currently it is only supported for OM.",
+    description = "CLI to update the highest index in transaction info table.",
     mixinStandardHelpOptions = true,
     versionProvider = HddsVersionProvider.class
 )
@@ -58,17 +59,18 @@ public class TransactionInfoRepair extends RepairTool {
 
   @CommandLine.Option(names = {"--term"},
       required = true,
-      description = "Highest term of transactionInfoTable. The input should be 
non-zero long integer.")
+      description = "Highest term to set. The input should be non-zero long 
integer.")
   private long highestTransactionTerm;
 
   @CommandLine.Option(names = {"--index"},
       required = true,
-      description = "Highest index of transactionInfoTable. The input should 
be non-zero long integer.")
+      description = "Highest index to set. The input should be non-zero long 
integer.")
   private long highestTransactionIndex;
 
   @Override
   public void execute() throws Exception {
-    if (checkIfServiceIsRunning("OM")) {
+    final Component component = getComponent();
+    if (checkIfServiceIsRunning(component.name())) {
       return;
     }
     List<ColumnFamilyHandle> cfHandleList = new ArrayList<>();
@@ -76,9 +78,10 @@ public void execute() throws Exception {
         dbPath);
 
     try (ManagedRocksDB db = ManagedRocksDB.open(dbPath, cfDescList, 
cfHandleList)) {
-      ColumnFamilyHandle transactionInfoCfh = 
RocksDBUtils.getColumnFamilyHandle(TRANSACTION_INFO_TABLE, cfHandleList);
+      String columnFamilyName = component.columnFamilyDefinition.getName();
+      ColumnFamilyHandle transactionInfoCfh = 
RocksDBUtils.getColumnFamilyHandle(columnFamilyName, cfHandleList);
       if (transactionInfoCfh == null) {
-        throw new IllegalArgumentException(TRANSACTION_INFO_TABLE +
+        throw new IllegalArgumentException(columnFamilyName +
             " is not in a column family in DB for the given path.");
       }
       TransactionInfo originalTransactionInfo =
@@ -102,11 +105,32 @@ public void execute() throws Exception {
       }
     } catch (RocksDBException exception) {
       error("Failed to update the RocksDB for the given path: %s", dbPath);
-      error(
-          "Make sure that Ozone entity (OM) is not running for the give 
database path and current host.");
       throw new IOException("Failed to update RocksDB.", exception);
     } finally {
       IOUtils.closeQuietly(cfHandleList);
     }
   }
+
+  private Component getComponent() {
+    final String parent = spec().parent().name();
+    switch (parent) {
+    case "om":
+      return Component.OM;
+    case "scm":
+      return Component.SCM;
+    default:
+      throw new IllegalStateException("Unknown component: " + parent);
+    }
+  }
+
+  private enum Component {
+    OM(OMDBDefinition.TRANSACTION_INFO_TABLE),
+    SCM(SCMDBDefinition.TRANSACTIONINFO);
+
+    private final DBColumnFamilyDefinition<String, TransactionInfo> 
columnFamilyDefinition;
+
+    Component(DBColumnFamilyDefinition<String, TransactionInfo> 
columnFamilyDefinition) {
+      this.columnFamilyDefinition = columnFamilyDefinition;
+    }
+  }
 }
diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/om/OMRepair.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/om/OMRepair.java
index c8e9f6e9e4..d738ec129b 100644
--- 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/om/OMRepair.java
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/om/OMRepair.java
@@ -19,6 +19,7 @@
 package org.apache.hadoop.ozone.repair.om;
 
 import org.apache.hadoop.hdds.cli.RepairSubcommand;
+import org.apache.hadoop.ozone.repair.TransactionInfoRepair;
 import org.apache.hadoop.ozone.repair.om.quota.QuotaRepair;
 import org.kohsuke.MetaInfServices;
 import picocli.CommandLine;
diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/scm/SCMRepair.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/scm/SCMRepair.java
index d7e61a8ed2..8ef59540a8 100644
--- 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/scm/SCMRepair.java
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/repair/scm/SCMRepair.java
@@ -19,6 +19,7 @@
 package org.apache.hadoop.ozone.repair.scm;
 
 import org.apache.hadoop.hdds.cli.RepairSubcommand;
+import org.apache.hadoop.ozone.repair.TransactionInfoRepair;
 import org.apache.hadoop.ozone.repair.scm.cert.CertRepair;
 import org.kohsuke.MetaInfServices;
 import picocli.CommandLine;
@@ -30,6 +31,7 @@
     description = "Operational tool to repair SCM.",
     subcommands = {
         CertRepair.class,
+        TransactionInfoRepair.class
     }
 )
 @MetaInfServices(RepairSubcommand.class)
diff --git 
a/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/repair/om/TestTransactionInfoRepair.java
 
b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/repair/TestTransactionInfoRepair.java
similarity index 75%
rename from 
hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/repair/om/TestTransactionInfoRepair.java
rename to 
hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/repair/TestTransactionInfoRepair.java
index 3ad1c4f840..f1ad9b57ed 100644
--- 
a/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/repair/om/TestTransactionInfoRepair.java
+++ 
b/hadoop-ozone/tools/src/test/java/org/apache/hadoop/ozone/repair/TestTransactionInfoRepair.java
@@ -15,18 +15,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.hadoop.ozone.repair.om;
+package org.apache.hadoop.ozone.repair;
 
+import org.apache.hadoop.hdds.scm.metadata.SCMDBDefinition;
 import org.apache.hadoop.hdds.utils.IOUtils;
 import org.apache.hadoop.hdds.utils.TransactionInfo;
 import org.apache.hadoop.hdds.utils.db.managed.ManagedRocksDB;
 import org.apache.hadoop.ozone.debug.RocksDBUtils;
-import org.apache.hadoop.ozone.repair.OzoneRepair;
+import org.apache.hadoop.ozone.om.codec.OMDBDefinition;
 import org.apache.ozone.test.GenericTestUtils;
 import org.apache.ratis.server.protocol.TermIndex;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 import org.mockito.MockedStatic;
 import org.rocksdb.ColumnFamilyHandle;
 import org.rocksdb.RocksDB;
@@ -35,7 +37,6 @@
 
 import static org.apache.ozone.test.IntLambda.withTextFromSystemIn;
 import static org.apache.hadoop.ozone.OzoneConsts.TRANSACTION_INFO_KEY;
-import static 
org.apache.hadoop.ozone.om.OmMetadataManagerImpl.TRANSACTION_INFO_TABLE;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.any;
@@ -51,7 +52,6 @@
  */
 public class TestTransactionInfoRepair {
 
-
   private static final String DB_PATH = "testDBPath";
   private static final long TEST_TERM = 1;
   private static final long TEST_INDEX = 1;
@@ -69,10 +69,11 @@ void cleanup() {
     IOUtils.closeQuietly(out, err);
   }
 
-  @Test
-  public void testUpdateTransactionInfoTableSuccessful() {
+  @ParameterizedTest
+  @ValueSource(strings = {"om", "scm"})
+  public void testUpdateTransactionInfoTableSuccessful(String component) {
     ManagedRocksDB mdb = mockRockDB();
-    testCommand(mdb, mock(ColumnFamilyHandle.class));
+    testCommand(component, mdb, mock(ColumnFamilyHandle.class));
 
     assertThat(out.getOutput())
         .contains(
@@ -81,16 +82,18 @@ public void testUpdateTransactionInfoTableSuccessful() {
         );
   }
 
-  @Test
-  public void testCommandWhenTableNotInDBForGivenPath() {
+  @ParameterizedTest
+  @ValueSource(strings = {"om", "scm"})
+  public void testCommandWhenTableNotInDBForGivenPath(String component) {
     ManagedRocksDB mdb = mockRockDB();
-    testCommand(mdb, null);
+    testCommand(component, mdb, null);
     assertThat(err.getOutput())
-        .contains(TRANSACTION_INFO_TABLE + " is not in a column family in DB 
for the given path");
+        .contains(getColumnFamilyName(component) + " is not in a column family 
in DB for the given path");
   }
 
-  @Test
-  public void testCommandWhenFailToUpdateRocksDBForGivenPath() throws 
Exception {
+  @ParameterizedTest
+  @ValueSource(strings = {"om", "scm"})
+  public void testCommandWhenFailToUpdateRocksDBForGivenPath(String component) 
throws Exception {
     ManagedRocksDB mdb = mockRockDB();
     RocksDB rdb = mdb.get();
 
@@ -98,18 +101,18 @@ public void 
testCommandWhenFailToUpdateRocksDBForGivenPath() throws Exception {
     doThrow(RocksDBException.class).when(rdb)
         .put(eq(mock), any(byte[].class), any(byte[].class));
 
-    testCommand(mdb, mock);
+    testCommand(component, mdb, mock);
 
     assertThat(err.getOutput())
         .contains("Failed to update RocksDB.");
   }
 
-
-  private void testCommand(ManagedRocksDB mdb, ColumnFamilyHandle 
columnFamilyHandle) {
+  private void testCommand(String component, ManagedRocksDB mdb, 
ColumnFamilyHandle columnFamilyHandle) {
+    final String expectedColumnFamilyName = getColumnFamilyName(component);
     try (MockedStatic<ManagedRocksDB> mocked = 
mockStatic(ManagedRocksDB.class);
          MockedStatic<RocksDBUtils> mockUtil = mockStatic(RocksDBUtils.class)) 
{
       mocked.when(() -> ManagedRocksDB.open(anyString(), anyList(), 
anyList())).thenReturn(mdb);
-      mockUtil.when(() -> RocksDBUtils.getColumnFamilyHandle(anyString(), 
anyList()))
+      mockUtil.when(() -> 
RocksDBUtils.getColumnFamilyHandle(eq(expectedColumnFamilyName), anyList()))
           .thenReturn(columnFamilyHandle);
 
       mockUtil.when(() -> RocksDBUtils.getValue(eq(mdb), 
eq(columnFamilyHandle), eq(TRANSACTION_INFO_KEY),
@@ -128,7 +131,7 @@ private void testCommand(ManagedRocksDB mdb, 
ColumnFamilyHandle columnFamilyHand
       CommandLine cli = new OzoneRepair().getCmd();
       withTextFromSystemIn("y")
           .execute(() -> cli.execute(
-              "om",
+              component,
               "update-transaction",
               "--db", DB_PATH,
               "--term", String.valueOf(TEST_TERM),
@@ -137,6 +140,14 @@ private void testCommand(ManagedRocksDB mdb, 
ColumnFamilyHandle columnFamilyHand
     }
   }
 
+  private String getColumnFamilyName(String component) {
+    switch (component) {
+    case "om": return OMDBDefinition.TRANSACTION_INFO_TABLE.getName();
+    case "scm": return SCMDBDefinition.TRANSACTIONINFO.getName();
+    default: return "";
+    }
+  }
+
   private ManagedRocksDB mockRockDB() {
     ManagedRocksDB db = mock(ManagedRocksDB.class);
     RocksDB rocksDB = mock(RocksDB.class);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to