|
53 | 53 | import org.junit.Assert; |
54 | 54 | import org.junit.Before; |
55 | 55 | import org.junit.BeforeClass; |
56 | | -import org.junit.Ignore; |
57 | 56 | import org.junit.Test; |
58 | 57 | import org.slf4j.Logger; |
59 | 58 | import org.slf4j.LoggerFactory; |
@@ -122,6 +121,17 @@ public class GoogleCloudSpannerTest extends DataprocETLTestBase { |
122 | 121 | Schema.Field.of("ARRAY_DATE_COL", Schema.arrayOf(Schema.nullableOf(Schema.of(Schema.LogicalType.DATE)))) |
123 | 122 | ); |
124 | 123 |
|
| 124 | + private static final Schema IMPORT_SCHEMA = Schema.recordOf( |
| 125 | + "schema", |
| 126 | + Schema.Field.of("ID", Schema.nullableOf(Schema.of(Schema.Type.LONG))), |
| 127 | + Schema.Field.of("StringCol", Schema.nullableOf(Schema.of(Schema.Type.STRING))), |
| 128 | + Schema.Field.of("BoolCol", Schema.nullableOf(Schema.of(Schema.Type.BOOLEAN))), |
| 129 | + Schema.Field.of("TimestampCol", Schema.nullableOf(Schema.of(Schema.LogicalType.TIMESTAMP_MICROS))), |
| 130 | + Schema.Field.of("ArrayIntCol", Schema.arrayOf(Schema.nullableOf(Schema.of(Schema.Type.LONG)))), |
| 131 | + Schema.Field.of("BytesCol", Schema.nullableOf(Schema.of(Schema.Type.BYTES))), |
| 132 | + Schema.Field.of("DateCol", Schema.nullableOf(Schema.of(Schema.LogicalType.DATE))) |
| 133 | + ); |
| 134 | + |
125 | 135 | private static final ZonedDateTime NOW = ZonedDateTime.now(); |
126 | 136 | private static final Function<String, List<Mutation>> TEST_MUTATIONS = (tableName) -> ImmutableList.of( |
127 | 137 | Mutation.newInsertBuilder(tableName) |
@@ -156,7 +166,17 @@ public class GoogleCloudSpannerTest extends DataprocETLTestBase { |
156 | 166 | Date.fromYearMonthDay(NOW.getYear(), NOW.getMonthValue(), NOW.getDayOfMonth()), |
157 | 167 | Date.fromYearMonthDay(NOW.getYear() + 1, NOW.getMonthValue(), NOW.getDayOfMonth()), |
158 | 168 | null)) |
159 | | - .build() |
| 169 | + .build(), |
| 170 | + |
| 171 | + Mutation.newInsertBuilder(tableName) |
| 172 | + .set("ID").to(3) |
| 173 | + .set("STRING_COL").to("some string") |
| 174 | + .set("BOOL_COL").to(false) |
| 175 | + .set("TIMESTAMP_COL").to(Timestamp.ofTimeSecondsAndNanos(NOW.toEpochSecond(), NOW.getNano())) |
| 176 | + .set("ARRAY_INT_COL").toInt64Array(Arrays.asList(1L, 2L, null)) |
| 177 | + .set("BYTES_COL").to(ByteArray.copyFrom("some value".getBytes())) |
| 178 | + .set("DATE_COL").to(Date.fromYearMonthDay(NOW.getYear(), NOW.getMonthValue(), NOW.getDayOfMonth())) |
| 179 | + .build() |
160 | 180 | ); |
161 | 181 |
|
162 | 182 | private static final List<Mutation> SOURCE_TABLE_TEST_MUTATIONS = TEST_MUTATIONS.apply(SOURCE_TABLE_NAME); |
@@ -306,6 +326,70 @@ private void testReadAndStore(Engine engine) throws Exception { |
306 | 326 | Assert.assertTrue(resultSet.isNull("NOT_IN_THE_SCHEMA_COL")); |
307 | 327 | } |
308 | 328 |
|
| 329 | + @Test |
| 330 | + public void testReadWithImportQuery() throws Exception { |
| 331 | + testReadWithImportQuery(Engine.MAPREDUCE); |
| 332 | + testReadWithImportQuery(Engine.SPARK); |
| 333 | + } |
| 334 | + |
| 335 | + private void testReadWithImportQuery(Engine engine) throws Exception { |
| 336 | + Map<String, String> sourceProperties = new ImmutableMap.Builder<String, String>() |
| 337 | + .put("referenceName", "spanner_source") |
| 338 | + .put("project", "${project}") |
| 339 | + .put("instance", "${instance}") |
| 340 | + .put("database", "${database}") |
| 341 | + .put("table", "${srcTable}") |
| 342 | + .put("importQuery","${importQuery}") |
| 343 | + .build(); |
| 344 | + |
| 345 | + Map<String, String> sinkProperties = new ImmutableMap.Builder<String, String>() |
| 346 | + .put("referenceName", "spanner_sink") |
| 347 | + .put("project", "${project}") |
| 348 | + .put("instance", "${instance}") |
| 349 | + .put("database", "${database}") |
| 350 | + .put("table", "${dstTable}") |
| 351 | + .put("schema", IMPORT_SCHEMA.toString()) |
| 352 | + .put("keys", "${keys}") |
| 353 | + .build(); |
| 354 | + |
| 355 | + String applicationName = SPANNER_PLUGIN_NAME + "-testReadWithImportQuery"; |
| 356 | + String nonExistentSinkTableName = "nonexistent_" + UUID.randomUUID().toString().replaceAll("-", "_"); |
| 357 | + ApplicationManager applicationManager = deployApplication(sourceProperties, sinkProperties, |
| 358 | + applicationName, engine); |
| 359 | + Map<String, String> args = new HashMap<>(); |
| 360 | + args.put("project", getProjectId()); |
| 361 | + args.put("instance", instance.getId().getInstance()); |
| 362 | + args.put("database", database.getId().getDatabase()); |
| 363 | + args.put("srcTable", SOURCE_TABLE_NAME); |
| 364 | + args.put("dstTable", nonExistentSinkTableName); |
| 365 | + args.put("keys", "ID"); |
| 366 | + args.put("importQuery","Select ID, STRING_COL as StringCol, BOOL_COL as BoolCol, TIMESTAMP_COL as TimestampCol, " + |
| 367 | + "ARRAY_INT_COL as ArrayIntCol, BYTES_COL as BytesCol, DATE_COL as DateCol from " + SOURCE_TABLE_NAME); |
| 368 | + startWorkFlow(applicationManager, ProgramRunStatus.COMPLETED, args); |
| 369 | + |
| 370 | + ResultSet resultSet = spanner.getDatabaseClient(database.getId()) |
| 371 | + .singleUse() |
| 372 | + .executeQuery(Statement.of(String.format("select * from %s;", nonExistentSinkTableName))); |
| 373 | + |
| 374 | + Assert.assertTrue(resultSet.next()); |
| 375 | + Map<String, Value> firstRowExpected = SOURCE_TABLE_TEST_MUTATIONS.get(0).asMap(); |
| 376 | + Assert.assertEquals(firstRowExpected.get("ID").getInt64(), resultSet.getLong("ID")); |
| 377 | + |
| 378 | + Assert.assertTrue(resultSet.next()); |
| 379 | + Assert.assertTrue(resultSet.next()); |
| 380 | + Map<String, Value> secondRowExpected = SOURCE_TABLE_TEST_MUTATIONS.get(2).asMap(); |
| 381 | + Assert.assertEquals(secondRowExpected.keySet().size(), resultSet.getColumnCount()); |
| 382 | + Assert.assertEquals(secondRowExpected.get("ID").getInt64(), resultSet.getLong("ID")); |
| 383 | + Assert.assertEquals(secondRowExpected.get("STRING_COL").getString(), resultSet.getString("StringCol")); |
| 384 | + Assert.assertEquals(secondRowExpected.get("BOOL_COL").getBool(), resultSet.getBoolean("BoolCol")); |
| 385 | + Assert.assertEquals(secondRowExpected.get("TIMESTAMP_COL").getTimestamp(), resultSet.getTimestamp("TimestampCol")); |
| 386 | + Assert.assertEquals(secondRowExpected.get("ARRAY_INT_COL").getInt64Array(), resultSet.getLongList("ArrayIntCol")); |
| 387 | + Assert.assertEquals(secondRowExpected.get("BYTES_COL").getBytes(), resultSet.getBytes("BytesCol")); |
| 388 | + Assert.assertEquals(secondRowExpected.get("DATE_COL").getDate(), resultSet.getDate("DateCol")); |
| 389 | + spanner.getDatabaseClient(database.getId()).singleUse() |
| 390 | + .executeQuery(Statement.of(String.format("drop table %s;", nonExistentSinkTableName))); |
| 391 | + } |
| 392 | + |
309 | 393 | //TODO:(CDAP-16040) re-enable once plugin is fixed |
310 | 394 | //@Test |
311 | 395 | public void testReadAndStoreInNewTableWithNoSourceSchema() throws Exception { |
|
0 commit comments