Skip to content

Commit 303b288

Browse files
committed
Table metadata service split to storage and transaction
1 parent c20b183 commit 303b288

File tree

8 files changed

+218
-123
lines changed

8 files changed

+218
-123
lines changed

data-loader/cli/src/main/java/com/scalar/db/dataloader/cli/command/dataexport/ExportCommand.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import com.scalar.db.dataloader.core.exception.KeyParsingException;
2828
import com.scalar.db.dataloader.core.tablemetadata.TableMetadataException;
2929
import com.scalar.db.dataloader.core.tablemetadata.TableMetadataService;
30+
import com.scalar.db.dataloader.core.tablemetadata.TableMetadataStorageService;
31+
import com.scalar.db.dataloader.core.tablemetadata.TableMetadataTransactionService;
3032
import com.scalar.db.dataloader.core.util.KeyUtils;
3133
import com.scalar.db.io.Key;
3234
import com.scalar.db.service.StorageFactory;
@@ -134,10 +136,10 @@ private TableMetadataService createTableMetadataService(
134136
ScalarDbMode scalarDbMode, String scalarDbPropertiesFilePath) throws IOException {
135137
if (scalarDbMode.equals(ScalarDbMode.TRANSACTION)) {
136138
TransactionFactory transactionFactory = TransactionFactory.create(scalarDbPropertiesFilePath);
137-
return new TableMetadataService(transactionFactory.getTransactionAdmin());
139+
return new TableMetadataTransactionService(transactionFactory.getTransactionAdmin());
138140
}
139141
StorageFactory storageFactory = StorageFactory.create(scalarDbPropertiesFilePath);
140-
return new TableMetadataService(storageFactory.getStorageAdmin());
142+
return new TableMetadataStorageService(storageFactory.getStorageAdmin());
141143
}
142144

143145
/**

data-loader/cli/src/main/java/com/scalar/db/dataloader/cli/command/dataimport/ImportCommand.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.scalar.db.dataloader.core.dataimport.processor.ImportProcessorFactory;
2525
import com.scalar.db.dataloader.core.tablemetadata.TableMetadataException;
2626
import com.scalar.db.dataloader.core.tablemetadata.TableMetadataService;
27+
import com.scalar.db.dataloader.core.tablemetadata.TableMetadataStorageService;
2728
import com.scalar.db.dataloader.core.util.TableMetadataUtil;
2829
import com.scalar.db.service.StorageFactory;
2930
import com.scalar.db.service.TransactionFactory;
@@ -109,7 +110,7 @@ private Map<String, TableMetadata> createTableMetadataMap(
109110
File configFile = new File(configFilePath);
110111
StorageFactory storageFactory = StorageFactory.create(configFile);
111112
try (DistributedStorageAdmin storageAdmin = storageFactory.getStorageAdmin()) {
112-
TableMetadataService tableMetadataService = new TableMetadataService(storageAdmin);
113+
TableMetadataService tableMetadataService = new TableMetadataStorageService(storageAdmin);
113114
Map<String, TableMetadata> tableMetadataMap = new HashMap<>();
114115
if (controlFile != null) {
115116
for (ControlFileTable table : controlFile.getTables()) {
Lines changed: 22 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,19 @@
11
package com.scalar.db.dataloader.core.tablemetadata;
22

3-
import com.scalar.db.api.DistributedStorageAdmin;
4-
import com.scalar.db.api.DistributedTransactionAdmin;
53
import com.scalar.db.api.TableMetadata;
64
import com.scalar.db.common.error.CoreError;
75
import com.scalar.db.dataloader.core.util.TableMetadataUtil;
8-
import com.scalar.db.exception.storage.ExecutionException;
96
import java.util.Collection;
107
import java.util.HashMap;
118
import java.util.Map;
12-
import lombok.RequiredArgsConstructor;
139

1410
/**
15-
* Service for retrieving {@link TableMetadata} from ScalarDB. Provides methods to fetch metadata
16-
* for individual tables or a collection of tables.
11+
* Abstract base class for retrieving {@link TableMetadata} from ScalarDB. Provides shared logic for
12+
* fetching metadata for a collection of tables. Subclasses must implement the specific logic for
13+
* fetching individual table metadata.
1714
*/
18-
@RequiredArgsConstructor
19-
public class TableMetadataService {
15+
public abstract class TableMetadataService {
2016

21-
private final DistributedStorageAdmin storageAdmin;
22-
private final DistributedTransactionAdmin transactionAdmin;
23-
24-
public TableMetadataService(DistributedStorageAdmin storageAdmin) {
25-
this.transactionAdmin = null;
26-
this.storageAdmin = storageAdmin;
27-
}
28-
29-
public TableMetadataService(DistributedTransactionAdmin transactionAdmin) {
30-
this.transactionAdmin = transactionAdmin;
31-
this.storageAdmin = null;
32-
}
3317
/**
3418
* Retrieves the {@link TableMetadata} for a specific namespace and table name.
3519
*
@@ -41,22 +25,12 @@ public TableMetadataService(DistributedTransactionAdmin transactionAdmin) {
4125
*/
4226
public TableMetadata getTableMetadata(String namespace, String tableName)
4327
throws TableMetadataException {
44-
try {
45-
TableMetadata tableMetadata = null;
46-
if (storageAdmin != null) {
47-
tableMetadata = storageAdmin.getTableMetadata(namespace, tableName);
48-
} else if (transactionAdmin != null) {
49-
tableMetadata = transactionAdmin.getTableMetadata(namespace, tableName);
50-
}
51-
if (tableMetadata == null) {
52-
throw new TableMetadataException(
53-
CoreError.DATA_LOADER_MISSING_NAMESPACE_OR_TABLE.buildMessage(namespace, tableName));
54-
}
55-
return tableMetadata;
56-
} catch (ExecutionException e) {
28+
TableMetadata metadata = getTableMetadataInternal(namespace, tableName);
29+
if (metadata == null) {
5730
throw new TableMetadataException(
58-
CoreError.DATA_LOADER_TABLE_METADATA_RETRIEVAL_FAILED.buildMessage(e.getMessage()), e);
31+
CoreError.DATA_LOADER_MISSING_NAMESPACE_OR_TABLE.buildMessage(namespace, tableName));
5932
}
33+
return metadata;
6034
}
6135

6236
/**
@@ -75,15 +49,25 @@ public TableMetadata getTableMetadata(String namespace, String tableName)
7549
public Map<String, TableMetadata> getTableMetadata(Collection<TableMetadataRequest> requests)
7650
throws TableMetadataException {
7751
Map<String, TableMetadata> metadataMap = new HashMap<>();
78-
7952
for (TableMetadataRequest request : requests) {
8053
String namespace = request.getNamespace();
8154
String tableName = request.getTable();
82-
TableMetadata tableMetadata = getTableMetadata(namespace, tableName);
55+
TableMetadata metadata = getTableMetadata(namespace, tableName);
8356
String key = TableMetadataUtil.getTableLookupKey(namespace, tableName);
84-
metadataMap.put(key, tableMetadata);
57+
metadataMap.put(key, metadata);
8558
}
86-
8759
return metadataMap;
8860
}
61+
62+
/**
63+
* Abstract method for retrieving table metadata for a specific namespace and table. Subclasses
64+
* must implement this to define how the metadata is fetched.
65+
*
66+
* @param namespace The namespace of the table.
67+
* @param tableName The table name.
68+
* @return The {@link TableMetadata} object, or null if not found.
69+
* @throws TableMetadataException if an error occurs during metadata retrieval.
70+
*/
71+
protected abstract TableMetadata getTableMetadataInternal(String namespace, String tableName)
72+
throws TableMetadataException;
8973
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.scalar.db.dataloader.core.tablemetadata;
2+
3+
import com.scalar.db.api.DistributedStorageAdmin;
4+
import com.scalar.db.api.TableMetadata;
5+
import com.scalar.db.common.error.CoreError;
6+
import com.scalar.db.exception.storage.ExecutionException;
7+
import lombok.RequiredArgsConstructor;
8+
9+
/**
10+
* Implementation of {@link TableMetadataService} that retrieves table metadata using {@link
11+
* DistributedStorageAdmin}.
12+
*/
13+
@RequiredArgsConstructor
14+
public class TableMetadataStorageService extends TableMetadataService {
15+
16+
private final DistributedStorageAdmin storageAdmin;
17+
18+
/**
19+
* Retrieves the {@link TableMetadata} for a given namespace and table using the {@link
20+
* DistributedStorageAdmin}.
21+
*
22+
* @param namespace The namespace of the table.
23+
* @param tableName The name of the table.
24+
* @return The {@link TableMetadata} for the specified table, or null if not found.
25+
* @throws TableMetadataException If an error occurs while fetching metadata.
26+
*/
27+
@Override
28+
protected TableMetadata getTableMetadataInternal(String namespace, String tableName)
29+
throws TableMetadataException {
30+
try {
31+
return storageAdmin.getTableMetadata(namespace, tableName);
32+
} catch (ExecutionException e) {
33+
throw new TableMetadataException(
34+
CoreError.DATA_LOADER_TABLE_METADATA_RETRIEVAL_FAILED.buildMessage(e.getMessage()), e);
35+
}
36+
}
37+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.scalar.db.dataloader.core.tablemetadata;
2+
3+
import com.scalar.db.api.DistributedTransactionAdmin;
4+
import com.scalar.db.api.TableMetadata;
5+
import com.scalar.db.common.error.CoreError;
6+
import com.scalar.db.exception.storage.ExecutionException;
7+
import lombok.RequiredArgsConstructor;
8+
9+
/**
10+
* Implementation of {@link TableMetadataService} that retrieves table metadata using {@link
11+
* DistributedTransactionAdmin}.
12+
*/
13+
@RequiredArgsConstructor
14+
public class TableMetadataTransactionService extends TableMetadataService {
15+
16+
private final DistributedTransactionAdmin transactionAdmin;
17+
18+
/**
19+
* Retrieves the {@link TableMetadata} for a given namespace and table using the {@link
20+
* DistributedTransactionAdmin}.
21+
*
22+
* @param namespace The namespace of the table.
23+
* @param tableName The name of the table.
24+
* @return The {@link TableMetadata} for the specified table, or null if not found.
25+
* @throws TableMetadataException If an error occurs while fetching metadata.
26+
*/
27+
@Override
28+
protected TableMetadata getTableMetadataInternal(String namespace, String tableName)
29+
throws TableMetadataException {
30+
try {
31+
return transactionAdmin.getTableMetadata(namespace, tableName);
32+
} catch (ExecutionException e) {
33+
throw new TableMetadataException(
34+
CoreError.DATA_LOADER_TABLE_METADATA_RETRIEVAL_FAILED.buildMessage(e.getMessage()), e);
35+
}
36+
}
37+
}

data-loader/core/src/test/java/com/scalar/db/dataloader/core/tablemetadata/TableMetadataServiceTest.java

Lines changed: 0 additions & 82 deletions
This file was deleted.
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.scalar.db.dataloader.core.tablemetadata;
2+
3+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
4+
5+
import com.scalar.db.api.DistributedStorageAdmin;
6+
import com.scalar.db.api.TableMetadata;
7+
import com.scalar.db.common.error.CoreError;
8+
import com.scalar.db.dataloader.core.UnitTestUtils;
9+
import com.scalar.db.exception.storage.ExecutionException;
10+
import java.util.Collections;
11+
import java.util.HashMap;
12+
import java.util.Map;
13+
import org.junit.jupiter.api.Assertions;
14+
import org.junit.jupiter.api.BeforeEach;
15+
import org.junit.jupiter.api.Test;
16+
import org.mockito.Mockito;
17+
18+
class TableMetadataStorageServiceTest {
19+
20+
DistributedStorageAdmin storageAdmin;
21+
TableMetadataService tableMetadataService;
22+
23+
@BeforeEach
24+
void setup() throws ExecutionException {
25+
storageAdmin = Mockito.mock(DistributedStorageAdmin.class);
26+
Mockito.when(storageAdmin.getTableMetadata("namespace", "table"))
27+
.thenReturn(UnitTestUtils.createTestTableMetadata());
28+
29+
tableMetadataService = new TableMetadataStorageService(storageAdmin);
30+
}
31+
32+
@Test
33+
void getTableMetadata_withValidNamespaceAndTable_shouldReturnTableMetadataMap()
34+
throws TableMetadataException {
35+
Map<String, TableMetadata> expected = new HashMap<>();
36+
expected.put("namespace.table", UnitTestUtils.createTestTableMetadata());
37+
38+
TableMetadataRequest tableMetadataRequest = new TableMetadataRequest("namespace", "table");
39+
Map<String, TableMetadata> output =
40+
tableMetadataService.getTableMetadata(Collections.singleton(tableMetadataRequest));
41+
42+
Assertions.assertEquals(expected.get("namespace.table"), output.get("namespace.table"));
43+
}
44+
45+
@Test
46+
void getTableMetadata_withInvalidNamespaceAndTable_shouldThrowException()
47+
throws ExecutionException {
48+
Mockito.when(storageAdmin.getTableMetadata("namespace2", "table2")).thenReturn(null);
49+
50+
TableMetadataRequest tableMetadataRequest = new TableMetadataRequest("namespace2", "table2");
51+
assertThatThrownBy(
52+
() ->
53+
tableMetadataService.getTableMetadata(Collections.singleton(tableMetadataRequest)))
54+
.isInstanceOf(TableMetadataException.class)
55+
.hasMessage(
56+
CoreError.DATA_LOADER_MISSING_NAMESPACE_OR_TABLE.buildMessage("namespace2", "table2"));
57+
}
58+
}

0 commit comments

Comments
 (0)