Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[297] Refactor config classes #480

Merged
merged 1 commit into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.xtable.conversion;

import java.util.List;

import lombok.Builder;
import lombok.NonNull;
import lombok.Value;

import com.google.common.base.Preconditions;

import org.apache.xtable.model.sync.SyncMode;

@Value
public class ConversionConfig {
// The source of the sync
@NonNull SourceTable sourceTable;
// One or more targets to sync the table metadata to
List<TargetTable> targetTables;
// The mode, incremental or snapshot
SyncMode syncMode;

@Builder
ConversionConfig(
@NonNull SourceTable sourceTable, List<TargetTable> targetTables, SyncMode syncMode) {
this.sourceTable = sourceTable;
this.targetTables = targetTables;
Preconditions.checkArgument(
targetTables != null && !targetTables.isEmpty(),
"Please provide at-least one format to sync");
this.syncMode = syncMode == null ? SyncMode.INCREMENTAL : syncMode;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.xtable.conversion;

import java.util.Properties;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;

import org.apache.hadoop.fs.Path;

import com.google.common.base.Preconditions;

/** Defines a reference to a table in a particular format. */
@Getter
@EqualsAndHashCode
class ExternalTable {
ashvina marked this conversation as resolved.
Show resolved Hide resolved
/** The name of the table. */
protected final @NonNull String name;
/** The format of the table (e.g. DELTA, ICEBERG, HUDI) */
protected final @NonNull String formatName;
/** The path to the root of the table or the metadata directory depending on the format */
protected final @NonNull String basePath;
/** Optional namespace for the table */
protected final String[] namespace;
/** The configuration for interacting with the catalog that manages this table */
protected final CatalogConfig catalogConfig;

/** Optional, additional properties that can be used to define interactions with the table */
protected final Properties additionalProperties;

ExternalTable(
@NonNull String name,
@NonNull String formatName,
@NonNull String basePath,
String[] namespace,
CatalogConfig catalogConfig,
Properties additionalProperties) {
this.name = name;
this.formatName = formatName;
this.basePath = sanitizeBasePath(basePath);
this.namespace = namespace;
this.catalogConfig = catalogConfig;
this.additionalProperties = additionalProperties;
}

protected String sanitizeBasePath(String tableBasePath) {
Path path = new Path(tableBasePath);
Preconditions.checkArgument(path.isAbsolute(), "Table base path must be absolute");
if (path.isAbsoluteAndSchemeAuthorityNull()) {
// assume this is local file system and append scheme
return "file://" + path;
} else if (path.toUri().getScheme().equals("file")) {
// add extra slashes
return "file://" + path.toUri().getPath();
} else {
return path.toString();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,29 @@

package org.apache.xtable.conversion;

import org.apache.xtable.spi.extractor.SourcePartitionSpecExtractor;
import java.util.Properties;

public interface HudiSourceConfig {
String getPartitionSpecExtractorClass();
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NonNull;

SourcePartitionSpecExtractor loadSourcePartitionSpecExtractor();
@EqualsAndHashCode(callSuper = true)
@Getter
public class SourceTable extends ExternalTable {
/** The path to the data files, defaults to the metadataPath */
@NonNull private final String dataPath;

@Builder(toBuilder = true)
public SourceTable(
String name,
String formatName,
String basePath,
String dataPath,
String[] namespace,
CatalogConfig catalogConfig,
Properties additionalProperties) {
super(name, formatName, basePath, namespace, catalogConfig, additionalProperties);
this.dataPath = dataPath == null ? this.getBasePath() : sanitizeBasePath(dataPath);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.xtable.conversion;

import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.Properties;

import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;

@Getter
@EqualsAndHashCode(callSuper = true)
public class TargetTable extends ExternalTable {
private final Duration metadataRetention;

@Builder(toBuilder = true)
public TargetTable(
String name,
String formatName,
String basePath,
String[] namespace,
CatalogConfig catalogConfig,
Duration metadataRetention,
Properties additionalProperties) {
super(name, formatName, basePath, namespace, catalogConfig, additionalProperties);
this.metadataRetention =
metadataRetention == null ? Duration.of(7, ChronoUnit.DAYS) : metadataRetention;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

import org.apache.hadoop.conf.Configuration;

import org.apache.xtable.conversion.PerTableConfig;
import org.apache.xtable.conversion.TargetTable;
import org.apache.xtable.model.InternalTable;
import org.apache.xtable.model.metadata.TableSyncMetadata;
import org.apache.xtable.model.schema.InternalPartitionField;
Expand Down Expand Up @@ -89,5 +89,5 @@ public interface ConversionTarget {
String getTableFormat();

/** Initializes the client with provided configuration */
void init(PerTableConfig perTableConfig, Configuration configuration);
void init(TargetTable targetTable, Configuration configuration);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.xtable.conversion;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.Test;

public class TestExternalTable {
@Test
void sanitizePath() {
ExternalTable tooManySlashes =
new ExternalTable("name", "hudi", "s3://bucket//path", null, null, null);
assertEquals("s3://bucket/path", tooManySlashes.getBasePath());

ExternalTable localFilePath =
new ExternalTable("name", "hudi", "/local/data//path", null, null, null);
assertEquals("file:///local/data/path", localFilePath.getBasePath());

ExternalTable properLocalFilePath =
new ExternalTable("name", "hudi", "file:///local/data//path", null, null, null);
assertEquals("file:///local/data/path", properLocalFilePath.getBasePath());
}

@Test
void errorIfRequiredArgsNotSet() {
assertThrows(
NullPointerException.class,
() -> new ExternalTable("name", "hudi", null, null, null, null));

assertThrows(
NullPointerException.class,
() -> new ExternalTable("name", null, "file://bucket/path", null, null, null));

assertThrows(
NullPointerException.class,
() -> new ExternalTable(null, "hudi", "file://bucket/path", null, null, null));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.xtable.conversion;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;

class TestSourceTable {
@Test
void dataPathDefaultsToMetadataPath() {
String basePath = "file:///path/to/table";
SourceTable sourceTable =
SourceTable.builder().name("name").formatName("hudi").basePath(basePath).build();
assertEquals(basePath, sourceTable.getDataPath());
}

@Test
void dataPathIsSanitized() {
String basePath = "file:///path/to/table";
String dataPath = "file:///path/to/table//data";
SourceTable sourceTable =
SourceTable.builder()
.name("name")
.formatName("hudi")
.basePath(basePath)
.dataPath(dataPath)
.build();
assertEquals("file:///path/to/table/data", sourceTable.getDataPath());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,18 @@

package org.apache.xtable.conversion;

import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;

import org.apache.xtable.model.sync.SyncMode;
import java.time.Duration;

public interface PerTableConfig {
int getTargetMetadataRetentionInHours();
import org.junit.jupiter.api.Test;

String getTableBasePath();

String getTableDataPath();

String getTableName();

HudiSourceConfig getHudiSourceConfig();

List<String> getTargetTableFormats();

SyncMode getSyncMode();

String[] getNamespace();

CatalogConfig getIcebergCatalogConfig();
class TestTargetTable {
@Test
void retentionDefaultsToSevenDays() {
String basePath = "file:///path/to/table";
TargetTable targetTable =
TargetTable.builder().name("name").formatName("hudi").basePath(basePath).build();
assertEquals(Duration.ofDays(7), targetTable.getMetadataRetention());
}
}
Loading