Skip to content

Commit 359a6af

Browse files
feeblefakieinv-jishnuypeckstadt
authored
Backport to branch(3) : Refactor Data Loader Import to Use DistributedTransactionManager for Storage Mode (#3184)
Co-authored-by: inv-jishnu <31100916+inv-jishnu@users.noreply.github.com> Co-authored-by: Peckstadt Yves <peckstadt.yves@gmail.com>
1 parent e514e84 commit 359a6af

32 files changed

+265
-429
lines changed

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

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public class ExportCommand extends ExportCommandOptions implements Callable<Inte
5555
public Integer call() throws Exception {
5656
validateDeprecatedOptions();
5757
applyDeprecatedOptions();
58+
warnAboutIgnoredDeprecatedOptions();
5859
String scalarDbPropertiesFilePath = getScalarDbPropertiesFilePath();
5960

6061
try {
@@ -141,6 +142,28 @@ private void validateDeprecatedOptions() {
141142
MAX_THREADS_OPTION_SHORT);
142143
}
143144

145+
/** Warns about deprecated options that are no longer used and have been completely ignored. */
146+
private void warnAboutIgnoredDeprecatedOptions() {
147+
CommandLine.ParseResult parseResult = spec.commandLine().getParseResult();
148+
boolean hasIncludeMetadata =
149+
parseResult.hasMatchedOption(DEPRECATED_INCLUDE_METADATA_OPTION)
150+
|| parseResult.hasMatchedOption(DEPRECATED_INCLUDE_METADATA_OPTION_SHORT);
151+
152+
if (hasIncludeMetadata) {
153+
// Use picocli's ANSI support for colored warning output
154+
CommandLine.Help.Ansi ansi = CommandLine.Help.Ansi.AUTO;
155+
String warning =
156+
ansi.string(
157+
"@|bold,yellow The "
158+
+ DEPRECATED_INCLUDE_METADATA_OPTION
159+
+ " option is deprecated and no longer has any effect. "
160+
+ "Use the 'scalar.db.consensus_commit.include_metadata.enabled' configuration property "
161+
+ "in your ScalarDB properties file to control whether transaction metadata is included in scan operations.|@");
162+
163+
logger.warn(warning);
164+
}
165+
}
166+
144167
private String getScalarDbPropertiesFilePath() {
145168
if (StringUtils.isBlank(configFilePath)) {
146169
throw new IllegalArgumentException(DataLoaderError.CONFIG_FILE_PATH_BLANK.buildMessage());
@@ -160,8 +183,7 @@ private void validateOutputDirectory() throws DirectoryValidationException {
160183

161184
private ExportManager createExportManager(
162185
TransactionFactory transactionFactory, ScalarDbDao scalarDbDao, FileFormat fileFormat) {
163-
ProducerTaskFactory taskFactory =
164-
new ProducerTaskFactory(delimiter, includeTransactionMetadata, prettyPrintJson);
186+
ProducerTaskFactory taskFactory = new ProducerTaskFactory(delimiter, prettyPrintJson);
165187
DistributedTransactionManager manager = transactionFactory.getTransactionManager();
166188
switch (fileFormat) {
167189
case JSON:
@@ -180,7 +202,6 @@ private ExportOptions buildExportOptions(Key partitionKey, ScanRange scanRange)
180202
ExportOptions.builder(namespace, table, partitionKey, outputFormat)
181203
.sortOrders(sortOrders)
182204
.excludeHeaderRow(excludeHeader)
183-
.includeTransactionMetadata(includeTransactionMetadata)
184205
.delimiter(delimiter)
185206
.limit(limit)
186207
.maxThreadCount(maxThreads)

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ public class ExportCommandOptions {
1919
public static final String MAX_THREADS_OPTION = "--max-threads";
2020
public static final String MAX_THREADS_OPTION_SHORT = "-mt";
2121
public static final String DEPRECATED_THREADS_OPTION = "--threads";
22+
public static final String DEPRECATED_INCLUDE_METADATA_OPTION = "--include-metadata";
23+
public static final String DEPRECATED_INCLUDE_METADATA_OPTION_SHORT = "-m";
2224

2325
@CommandLine.Option(
2426
names = {"--config", "-c"},
@@ -69,10 +71,19 @@ public class ExportCommandOptions {
6971
defaultValue = "json")
7072
protected FileFormat outputFormat;
7173

74+
/**
75+
* @deprecated As of release 3.17.0 This option is no longer used and will be removed in release
76+
* 4.0.0. The option is not fully removed as users who might already have their scripts or
77+
* commands pre-set might pass the argument and when passed if not supported, picocli will
78+
* throw an error. We want to avoid that and instead just show a warning.
79+
*/
80+
@Deprecated
7281
@CommandLine.Option(
7382
names = {"--include-metadata", "-m"},
74-
description = "Include transaction metadata in the exported data (default: false)",
75-
defaultValue = "false")
83+
description =
84+
"Deprecated: This option is no longer used. Please use scalar.db.consensus_commit.include_metadata.enabled to control whether transaction metadata is included in scan operations.",
85+
defaultValue = "false",
86+
hidden = true)
7687
protected boolean includeTransactionMetadata;
7788

7889
@CommandLine.Option(

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

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,10 @@
88
import com.scalar.db.api.TableMetadata;
99
import com.scalar.db.dataloader.core.DataLoaderError;
1010
import com.scalar.db.dataloader.core.FileFormat;
11-
import com.scalar.db.dataloader.core.ScalarDbMode;
1211
import com.scalar.db.dataloader.core.dataimport.ImportManager;
1312
import com.scalar.db.dataloader.core.dataimport.ImportOptions;
1413
import com.scalar.db.dataloader.core.dataimport.controlfile.ControlFile;
1514
import com.scalar.db.dataloader.core.dataimport.controlfile.ControlFileTable;
16-
import com.scalar.db.dataloader.core.dataimport.dao.ScalarDbStorageManager;
17-
import com.scalar.db.dataloader.core.dataimport.dao.ScalarDbTransactionManager;
1815
import com.scalar.db.dataloader.core.dataimport.log.ImportLoggerConfig;
1916
import com.scalar.db.dataloader.core.dataimport.log.LogMode;
2017
import com.scalar.db.dataloader.core.dataimport.log.SingleFileImportLogger;
@@ -26,7 +23,6 @@
2623
import com.scalar.db.dataloader.core.tablemetadata.TableMetadataException;
2724
import com.scalar.db.dataloader.core.tablemetadata.TableMetadataService;
2825
import com.scalar.db.dataloader.core.util.TableMetadataUtil;
29-
import com.scalar.db.service.StorageFactory;
3026
import com.scalar.db.service.TransactionFactory;
3127
import java.io.BufferedReader;
3228
import java.io.File;
@@ -150,32 +146,14 @@ private ImportManager createImportManager(
150146
throws IOException {
151147
File configFile = new File(configFilePath);
152148
ImportProcessorFactory importProcessorFactory = new DefaultImportProcessorFactory();
153-
ImportManager importManager;
154-
if (scalarDbMode == ScalarDbMode.TRANSACTION) {
155-
ScalarDbTransactionManager scalarDbTransactionManager =
156-
new ScalarDbTransactionManager(TransactionFactory.create(configFile));
157-
importManager =
158-
new ImportManager(
159-
tableMetadataMap,
160-
reader,
161-
importOptions,
162-
importProcessorFactory,
163-
ScalarDbMode.TRANSACTION,
164-
null,
165-
scalarDbTransactionManager.getDistributedTransactionManager());
166-
} else {
167-
ScalarDbStorageManager scalarDbStorageManager =
168-
new ScalarDbStorageManager(StorageFactory.create(configFile));
169-
importManager =
170-
new ImportManager(
171-
tableMetadataMap,
172-
reader,
173-
importOptions,
174-
importProcessorFactory,
175-
ScalarDbMode.STORAGE,
176-
scalarDbStorageManager.getDistributedStorage(),
177-
null);
178-
}
149+
ImportManager importManager =
150+
new ImportManager(
151+
tableMetadataMap,
152+
reader,
153+
importOptions,
154+
importProcessorFactory,
155+
scalarDbMode,
156+
TransactionFactory.create(configFile).getTransactionManager());
179157
if (importOptions.getLogMode().equals(LogMode.SPLIT_BY_DATA_CHUNK)) {
180158
importManager.addListener(new SplitByDataChunkImportLogger(config, logWriterFactory));
181159
} else {

data-loader/cli/src/test/java/com/scalar/db/dataloader/cli/command/dataexport/ExportCommandTest.java

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.scalar.db.dataloader.cli.command.dataexport;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertFalse;
45
import static org.junit.jupiter.api.Assertions.assertThrows;
56
import static org.junit.jupiter.api.Assertions.assertTrue;
67

@@ -152,14 +153,14 @@ void call_withOnlyDeprecatedStartExclusive_shouldApplyInvertedValue() {
152153
cmd.parseArgs(args);
153154

154155
// Verify the deprecated value was parsed
155-
assertEquals(true, command.startExclusiveDeprecated);
156+
assertTrue(command.startExclusiveDeprecated);
156157

157158
// Apply deprecated options (this is what the command does after validation)
158159
command.applyDeprecatedOptions();
159160

160161
// Verify the value was applied with inverted logic
161162
// start-exclusive=true should become start-inclusive=false
162-
assertEquals(false, command.scanStartInclusive);
163+
assertFalse(command.scanStartInclusive);
163164
}
164165

165166
@Test
@@ -181,14 +182,14 @@ void call_withOnlyDeprecatedEndExclusive_shouldApplyInvertedValue() {
181182
cmd.parseArgs(args);
182183

183184
// Verify the deprecated value was parsed
184-
assertEquals(false, command.endExclusiveDeprecated);
185+
assertFalse(command.endExclusiveDeprecated);
185186

186187
// Apply deprecated options (this is what the command does after validation)
187188
command.applyDeprecatedOptions();
188189

189190
// Verify the value was applied with inverted logic
190191
// end-exclusive=false should become end-inclusive=true
191-
assertEquals(true, command.scanEndInclusive);
192+
assertTrue(command.scanEndInclusive);
192193
}
193194

194195
@Test
@@ -273,4 +274,83 @@ void call_withoutMaxThreads_shouldDefaultToAvailableProcessors() {
273274
// Verify it was set to available processors
274275
assertEquals(Runtime.getRuntime().availableProcessors(), command.maxThreads);
275276
}
277+
278+
@Test
279+
void call_withDeprecatedIncludeMetadataOption_shouldParseAndDetectOption() {
280+
// Test that the deprecated option can be parsed without crashing
281+
// and is detected for warning purposes (both long and short forms)
282+
String[] argsWithLongForm = {
283+
"--config",
284+
"scalardb.properties",
285+
"--namespace",
286+
"scalar",
287+
"--table",
288+
"asset",
289+
"--format",
290+
"JSON",
291+
"--include-metadata"
292+
};
293+
294+
String[] argsWithShortForm = {
295+
"--config",
296+
"scalardb.properties",
297+
"--namespace",
298+
"scalar",
299+
"--table",
300+
"asset",
301+
"--format",
302+
"JSON",
303+
"-m"
304+
};
305+
306+
// Test long form
307+
ExportCommand commandLong = new ExportCommand();
308+
CommandLine cmdLong = new CommandLine(commandLong);
309+
cmdLong.parseArgs(argsWithLongForm);
310+
commandLong.spec = cmdLong.getCommandSpec();
311+
312+
// Verify the option is detected (so warning will trigger)
313+
assertTrue(
314+
cmdLong
315+
.getParseResult()
316+
.hasMatchedOption(ExportCommandOptions.DEPRECATED_INCLUDE_METADATA_OPTION));
317+
318+
// Test short form
319+
ExportCommand commandShort = new ExportCommand();
320+
CommandLine cmdShort = new CommandLine(commandShort);
321+
cmdShort.parseArgs(argsWithShortForm);
322+
commandShort.spec = cmdShort.getCommandSpec();
323+
324+
// Verify the short option is detected (so warning will trigger)
325+
assertTrue(
326+
cmdShort
327+
.getParseResult()
328+
.hasMatchedOption(ExportCommandOptions.DEPRECATED_INCLUDE_METADATA_OPTION_SHORT));
329+
}
330+
331+
@Test
332+
void call_withoutDeprecatedIncludeMetadataOption_shouldNotDetectOption() {
333+
// Verify that when the deprecated option is NOT used, it's not detected
334+
// (so warning won't trigger incorrectly)
335+
String[] args = {
336+
"--config",
337+
"scalardb.properties",
338+
"--namespace",
339+
"scalar",
340+
"--table",
341+
"asset",
342+
"--format",
343+
"JSON"
344+
};
345+
346+
ExportCommand command = new ExportCommand();
347+
CommandLine cmd = new CommandLine(command);
348+
cmd.parseArgs(args);
349+
command.spec = cmd.getCommandSpec();
350+
351+
// Verify the option is NOT detected (so warning won't trigger)
352+
assertFalse(
353+
cmd.getParseResult()
354+
.hasMatchedOption(ExportCommandOptions.DEPRECATED_INCLUDE_METADATA_OPTION));
355+
}
276356
}

data-loader/core/src/main/java/com/scalar/db/dataloader/core/dataexport/CsvExportManager.java

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import com.scalar.db.dataloader.core.dataexport.producer.ProducerTaskFactory;
66
import com.scalar.db.dataloader.core.dataimport.dao.ScalarDbDao;
77
import com.scalar.db.dataloader.core.util.CsvUtil;
8-
import com.scalar.db.transaction.consensuscommit.ConsensusCommitUtils;
98
import java.io.IOException;
109
import java.io.Writer;
1110
import java.util.Iterator;
@@ -77,8 +76,7 @@ private String createCsvHeaderRow(ExportOptions exportOptions, TableMetadata tab
7776
Iterator<String> iterator = tableMetadata.getColumnNames().iterator();
7877
while (iterator.hasNext()) {
7978
String columnName = iterator.next();
80-
if (shouldIgnoreColumn(
81-
exportOptions.isIncludeTransactionMetadata(), columnName, tableMetadata, projections)) {
79+
if (!projections.isEmpty() && !projections.contains(columnName)) {
8280
continue;
8381
}
8482
headerRow.append(columnName);
@@ -90,24 +88,4 @@ private String createCsvHeaderRow(ExportOptions exportOptions, TableMetadata tab
9088
headerRow.append("\n");
9189
return headerRow.toString();
9290
}
93-
94-
/**
95-
* To ignore a column or not based on conditions such as if it is a metadata column or if it is
96-
* not include in selected projections
97-
*
98-
* @param isIncludeTransactionMetadata to include transaction metadata or not
99-
* @param columnName column name
100-
* @param tableMetadata table metadata
101-
* @param projections selected columns for projection
102-
* @return ignore the column or not
103-
*/
104-
private boolean shouldIgnoreColumn(
105-
boolean isIncludeTransactionMetadata,
106-
String columnName,
107-
TableMetadata tableMetadata,
108-
List<String> projections) {
109-
return (!isIncludeTransactionMetadata
110-
&& ConsensusCommitUtils.isTransactionMetaColumn(columnName, tableMetadata))
111-
|| (!projections.isEmpty() && !projections.contains(columnName));
112-
}
11391
}

data-loader/core/src/main/java/com/scalar/db/dataloader/core/dataexport/ExportManager.java

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import com.scalar.db.dataloader.core.dataexport.validation.ExportOptionsValidator;
1212
import com.scalar.db.dataloader.core.dataimport.dao.ScalarDbDao;
1313
import com.scalar.db.dataloader.core.dataimport.dao.ScalarDbDaoException;
14-
import com.scalar.db.dataloader.core.util.TableMetadataUtil;
1514
import com.scalar.db.exception.transaction.CrudException;
1615
import com.scalar.db.exception.transaction.UnknownTransactionStatusException;
1716
import com.scalar.db.io.DataType;
@@ -76,7 +75,6 @@ public ExportReport startExport(
7675
try {
7776
validateExportOptions(exportOptions, tableMetadata);
7877
Map<String, DataType> dataTypeByColumnName = tableMetadata.getColumnDataTypes();
79-
handleTransactionMetadata(exportOptions, tableMetadata);
8078
processHeader(exportOptions, tableMetadata, writer);
8179

8280
ExecutorService executorService =
@@ -198,22 +196,6 @@ private void validateExportOptions(ExportOptions exportOptions, TableMetadata ta
198196
ExportOptionsValidator.validate(exportOptions, tableMetadata);
199197
}
200198

201-
/**
202-
* To update projection columns of export options if include metadata options is enabled
203-
*
204-
* @param exportOptions export options
205-
* @param tableMetadata metadata of the table
206-
*/
207-
private void handleTransactionMetadata(ExportOptions exportOptions, TableMetadata tableMetadata) {
208-
if (exportOptions.isIncludeTransactionMetadata()
209-
&& !exportOptions.getProjectionColumns().isEmpty()) {
210-
List<String> projectionMetadata =
211-
TableMetadataUtil.populateProjectionsWithMetadata(
212-
tableMetadata, exportOptions.getProjectionColumns());
213-
exportOptions.setProjectionColumns(projectionMetadata);
214-
}
215-
}
216-
217199
/**
218200
* To create a scanner object
219201
*

data-loader/core/src/main/java/com/scalar/db/dataloader/core/dataexport/ExportOptions.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ public class ExportOptions {
2727
@Builder.Default private final int maxThreadCount = Runtime.getRuntime().availableProcessors();
2828
@Builder.Default private final String delimiter = ";";
2929
@Builder.Default private final boolean excludeHeaderRow = false;
30-
@Builder.Default private final boolean includeTransactionMetadata = false;
3130
@Builder.Default private List<String> projectionColumns = Collections.emptyList();
3231
private List<Scan.Ordering> sortOrders;
3332

0 commit comments

Comments
 (0)