|
18 | 18 | package org.apache.flink.cdc.connectors.iceberg.sink; |
19 | 19 |
|
20 | 20 | import org.apache.flink.cdc.common.configuration.Configuration; |
| 21 | +import org.apache.flink.cdc.common.event.CreateTableEvent; |
| 22 | +import org.apache.flink.cdc.common.event.TableId; |
21 | 23 | import org.apache.flink.cdc.common.factories.DataSinkFactory; |
22 | 24 | import org.apache.flink.cdc.common.factories.FactoryHelper; |
| 25 | +import org.apache.flink.cdc.common.schema.Schema; |
23 | 26 | import org.apache.flink.cdc.common.sink.DataSink; |
| 27 | +import org.apache.flink.cdc.common.types.DataTypes; |
24 | 28 | import org.apache.flink.cdc.composer.utils.FactoryDiscoveryUtils; |
25 | 29 | import org.apache.flink.table.api.ValidationException; |
26 | 30 |
|
27 | 31 | import org.apache.flink.shaded.guava31.com.google.common.collect.ImmutableMap; |
28 | 32 |
|
| 33 | +import org.apache.iceberg.CatalogUtil; |
| 34 | +import org.apache.iceberg.PartitionSpec; |
| 35 | +import org.apache.iceberg.Table; |
| 36 | +import org.apache.iceberg.catalog.Catalog; |
| 37 | +import org.apache.iceberg.catalog.TableIdentifier; |
29 | 38 | import org.assertj.core.api.Assertions; |
30 | 39 | import org.junit.jupiter.api.Test; |
| 40 | +import org.junit.jupiter.api.io.TempDir; |
| 41 | + |
| 42 | +import java.io.File; |
| 43 | +import java.util.HashMap; |
| 44 | +import java.util.Map; |
| 45 | +import java.util.UUID; |
31 | 46 |
|
32 | 47 | /** Tests for {@link IcebergDataSinkFactory}. */ |
33 | 48 | public class IcebergDataSinkFactoryTest { |
| 49 | + @TempDir public static java.nio.file.Path temporaryFolder; |
34 | 50 |
|
35 | 51 | @Test |
36 | 52 | void testCreateDataSink() { |
@@ -92,4 +108,77 @@ void testPrefixRequireOption() { |
92 | 108 | conf, conf, Thread.currentThread().getContextClassLoader())); |
93 | 109 | Assertions.assertThat(dataSink).isInstanceOf(IcebergDataSink.class); |
94 | 110 | } |
| 111 | + |
| 112 | + @Test |
| 113 | + public void testPartitionOption() { |
| 114 | + Map<String, String> testcases = new HashMap<>(); |
| 115 | + testcases.put("test.iceberg_partition_table:year(create_time)", "create_time_year"); |
| 116 | + testcases.put("test.iceberg_partition_table:month(create_time)", "create_time_month"); |
| 117 | + testcases.put("test.iceberg_partition_table:day(create_time)", "create_time_day"); |
| 118 | + testcases.put("test.iceberg_partition_table:hour(create_time)", "create_time_hour"); |
| 119 | + testcases.put("test.iceberg_partition_table:bucket[8](create_time)", "create_time_bucket"); |
| 120 | + testcases.put("test.iceberg_partition_table:create_time", "create_time"); |
| 121 | + testcases.put("test.iceberg_partition_table:truncate[8](id)", "id_trunc"); |
| 122 | + |
| 123 | + for (Map.Entry<String, String> entry : testcases.entrySet()) { |
| 124 | + runTestPartitionOption(entry.getKey(), entry.getValue()); |
| 125 | + } |
| 126 | + } |
| 127 | + |
| 128 | + public void runTestPartitionOption(String partitionKey, String transformColumnName) { |
| 129 | + Map<String, String> catalogOptions = new HashMap<>(); |
| 130 | + String warehouse = |
| 131 | + new File(temporaryFolder.toFile(), UUID.randomUUID().toString()).toString(); |
| 132 | + catalogOptions.put("type", "hadoop"); |
| 133 | + catalogOptions.put("warehouse", warehouse); |
| 134 | + catalogOptions.put("cache-enabled", "false"); |
| 135 | + Catalog catalog = |
| 136 | + CatalogUtil.buildIcebergCatalog( |
| 137 | + "cdc-iceberg-catalog", |
| 138 | + catalogOptions, |
| 139 | + new org.apache.hadoop.conf.Configuration()); |
| 140 | + |
| 141 | + Map<String, String> catalogConf = new HashMap<>(); |
| 142 | + for (Map.Entry<String, String> entry : catalogOptions.entrySet()) { |
| 143 | + catalogConf.put( |
| 144 | + IcebergDataSinkOptions.PREFIX_CATALOG_PROPERTIES + entry.getKey(), |
| 145 | + entry.getValue()); |
| 146 | + } |
| 147 | + IcebergDataSinkFactory sinkFactory = new IcebergDataSinkFactory(); |
| 148 | + Configuration conf = Configuration.fromMap(catalogConf); |
| 149 | + conf.set(IcebergDataSinkOptions.PARTITION_KEY, partitionKey); |
| 150 | + DataSink dataSink = |
| 151 | + sinkFactory.createDataSink( |
| 152 | + new FactoryHelper.DefaultContext( |
| 153 | + conf, conf, Thread.currentThread().getContextClassLoader())); |
| 154 | + |
| 155 | + TableId tableId = TableId.parse("test.iceberg_partition_table"); |
| 156 | + CreateTableEvent createTableEvent = |
| 157 | + new CreateTableEvent( |
| 158 | + tableId, |
| 159 | + Schema.newBuilder() |
| 160 | + .physicalColumn( |
| 161 | + "id", |
| 162 | + DataTypes.BIGINT().notNull(), |
| 163 | + "column for id", |
| 164 | + "AUTO_DECREMENT()") |
| 165 | + .physicalColumn( |
| 166 | + "create_time", |
| 167 | + DataTypes.TIMESTAMP().notNull(), |
| 168 | + "column for name", |
| 169 | + null) |
| 170 | + .primaryKey("id") |
| 171 | + .build()); |
| 172 | + |
| 173 | + dataSink.getMetadataApplier().applySchemaChange(createTableEvent); |
| 174 | + |
| 175 | + Table table = |
| 176 | + catalog.loadTable( |
| 177 | + TableIdentifier.of(tableId.getSchemaName(), tableId.getTableName())); |
| 178 | + |
| 179 | + Assertions.assertThat(table.specs().size()).isEqualTo(1); |
| 180 | + PartitionSpec spec = table.specs().get(0); |
| 181 | + Assertions.assertThat(spec.isPartitioned()).isTrue(); |
| 182 | + Assertions.assertThat(spec.rawPartitionType().field(transformColumnName)).isNotNull(); |
| 183 | + } |
95 | 184 | } |
0 commit comments