From 5cda88dd0a7292355a644ba5dcff91211dfbe126 Mon Sep 17 00:00:00 2001 From: liferoad Date: Wed, 15 Jan 2025 09:43:47 -0500 Subject: [PATCH 1/8] Switch to Java 17 for all Dataflow Templates (#2050) * [DO NOT MERGE] Test Java 17 * Polished the test * changed other places to java 17 * mvn spotless:apply * updated maven and maven plugin versions * fixed action.yml * changed maven-plugin.version * changed maven-dependency-plugin.version * use System.out.printf * updated the new hash caused by Java 17 --- .github/actions/setup-env/action.yml | 2 +- .github/actions/setup-java-env/action.yml | 2 +- contributor-docs/code-contributions.md | 2 +- .../it/gcp/artifacts/matchers/ArtifactsSubject.java | 11 +++++++++++ metadata/pom.xml | 4 ++-- plaintext-logging/pom.xml | 2 +- plugins/core-plugin/pom.xml | 4 ++-- .../cloud/teleport/plugin/DockerfileGenerator.java | 2 +- plugins/templates-maven-plugin/pom.xml | 8 ++++---- .../plugin/maven/TemplatesReleaseFinishMojo.java | 2 +- pom.xml | 4 ++-- python/pom.xml | 4 ++-- v1/pom.xml | 2 +- .../cloud/teleport/templates/BulkCompressorIT.java | 2 +- .../docs/AstraDbToBigQuery/README.md | 2 +- v2/azure-eventhub-to-pubsub/README.md | 2 +- v2/bigquery-to-bigtable/README.md | 2 +- v2/bigquery-to-parquet/README.md | 2 +- v2/datastream-to-bigquery/README.md | 2 +- v2/datastream-to-mongodb/readme.md | 2 +- v2/datastream-to-postgres/README.md | 2 +- v2/datastream-to-spanner/README.md | 2 +- v2/datastream-to-sql/README.md | 2 +- v2/file-format-conversion/README.md | 2 +- v2/gcs-to-sourcedb/README.md | 2 +- .../docs/BigQueryToElasticsearch/README.md | 2 +- .../docs/GCSToElasticsearch/README.md | 2 +- .../docs/PubSubToElasticsearch/README.md | 2 +- .../docs/SpannerChangeStreamsToGcs/README.md | 2 +- .../docs/SpannerToBigQuery/README.md | 2 +- .../docs/BigQueryToMongoDb/README.md | 2 +- v2/googlecloud-to-neo4j/docs/README.md | 2 +- v2/googlecloud-to-splunk/docs/GCSToSplunk/README.md | 2 +- v2/jms-to-pubsub/README.md | 2 +- v2/kafka-to-bigquery/README.md | 2 +- v2/kafka-to-gcs/README.md | 2 +- v2/kinesis-to-pubsub/README.md | 2 +- v2/kudu-to-bigquery/README.md | 2 +- .../docs/MongoDbToBigQuery/README.md | 2 +- .../docs/MongoDbToBigQueryCDC/README.md | 2 +- v2/mqtt-to-pubsub/README.md | 2 +- v2/pom.xml | 2 +- .../docs/PubSubAvroToBigQuery/README.md | 2 +- .../docs/PubSubProtoToBigQuery/README.md | 2 +- v2/pubsub-cdc-to-bigquery/README.md | 2 +- v2/pubsub-to-jms/README.md | 2 +- v2/pubsub-to-mongodb/README.md | 2 +- v2/pubsub-to-redis/README.md | 2 +- v2/sourcedb-to-spanner/README.md | 2 +- .../README.md | 2 +- v2/streaming-data-generator/README.md | 2 +- yaml/pom.xml | 4 ++-- 52 files changed, 70 insertions(+), 59 deletions(-) diff --git a/.github/actions/setup-env/action.yml b/.github/actions/setup-env/action.yml index 8ef59df42a..4f2a968de2 100644 --- a/.github/actions/setup-env/action.yml +++ b/.github/actions/setup-env/action.yml @@ -35,7 +35,7 @@ inputs: type: string description: 'The version of Java to install' required: false - default: '11' + default: '17' go-version: type: string description: 'The version of Go to install' diff --git a/.github/actions/setup-java-env/action.yml b/.github/actions/setup-java-env/action.yml index c3b50c7158..1d736f179c 100644 --- a/.github/actions/setup-java-env/action.yml +++ b/.github/actions/setup-java-env/action.yml @@ -30,7 +30,7 @@ inputs: type: string description: 'The version of Java to install' required: false - default: '11' + default: '17' outputs: cache-hit: description: 'Whether or not there was a cache hit' diff --git a/contributor-docs/code-contributions.md b/contributor-docs/code-contributions.md index 0e3f6efceb..073881adfa 100644 --- a/contributor-docs/code-contributions.md +++ b/contributor-docs/code-contributions.md @@ -28,7 +28,7 @@ these can be found in the following locations: ### Requirements -* Java 11 +* Java 17 * Maven 3 * IntelliJ (recommended) or another editor of your choice diff --git a/it/google-cloud-platform/src/main/java/org/apache/beam/it/gcp/artifacts/matchers/ArtifactsSubject.java b/it/google-cloud-platform/src/main/java/org/apache/beam/it/gcp/artifacts/matchers/ArtifactsSubject.java index 06ea14d039..770f32386d 100644 --- a/it/google-cloud-platform/src/main/java/org/apache/beam/it/gcp/artifacts/matchers/ArtifactsSubject.java +++ b/it/google-cloud-platform/src/main/java/org/apache/beam/it/gcp/artifacts/matchers/ArtifactsSubject.java @@ -36,6 +36,8 @@ import org.apache.beam.it.gcp.artifacts.utils.JsonTestUtil; import org.apache.beam.it.gcp.artifacts.utils.ParquetTestUtil; import org.apache.beam.it.truthmatchers.RecordsSubject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Subject that has assertion operations for artifact lists (GCS files), usually coming from the @@ -46,6 +48,8 @@ }) public final class ArtifactsSubject extends Subject { + private static final Logger LOG = LoggerFactory.getLogger(ArtifactsSubject.class); + private final List actual; private static final ObjectMapper objectMapper = new ObjectMapper(); @@ -96,8 +100,15 @@ public void hasContent(String content) { * @param hash Content to search for */ public void hasHash(String hash) { + if (actual.stream() .noneMatch(artifact -> sha256().hashBytes(artifact.contents()).toString().equals(hash))) { + actual.stream() + .forEach( + artifact -> { + String calculatedHash = sha256().hashBytes(artifact.contents()).toString(); + System.out.printf("Calculated Hash (no match found): {%s} \n", calculatedHash); + }); failWithActual("expected to contain hash", hash); } } diff --git a/metadata/pom.xml b/metadata/pom.xml index 674388eb91..a7dc4b3269 100644 --- a/metadata/pom.xml +++ b/metadata/pom.xml @@ -34,8 +34,8 @@ https://github.com/GoogleCloudPlatform/DataflowTemplates - 11 - 11 + 17 + 17 diff --git a/plaintext-logging/pom.xml b/plaintext-logging/pom.xml index 723de36fcc..d1d731dd86 100644 --- a/plaintext-logging/pom.xml +++ b/plaintext-logging/pom.xml @@ -27,7 +27,7 @@ plaintext-logging - 11 + 17 2.21.0 diff --git a/plugins/core-plugin/pom.xml b/plugins/core-plugin/pom.xml index 68e4ac0079..e29e8f4e9b 100644 --- a/plugins/core-plugin/pom.xml +++ b/plugins/core-plugin/pom.xml @@ -32,8 +32,8 @@ https://github.com/GoogleCloudPlatform/DataflowTemplates - 11 - 11 + 17 + 17 0.9.11 2.9.1 diff --git a/plugins/core-plugin/src/main/java/com/google/cloud/teleport/plugin/DockerfileGenerator.java b/plugins/core-plugin/src/main/java/com/google/cloud/teleport/plugin/DockerfileGenerator.java index 35b4181ecc..575470db27 100644 --- a/plugins/core-plugin/src/main/java/com/google/cloud/teleport/plugin/DockerfileGenerator.java +++ b/plugins/core-plugin/src/main/java/com/google/cloud/teleport/plugin/DockerfileGenerator.java @@ -43,7 +43,7 @@ public class DockerfileGenerator { public static final String BASE_CONTAINER_IMAGE = - "gcr.io/dataflow-templates-base/java11-template-launcher-base-distroless:latest"; + "gcr.io/dataflow-templates-base/java17-template-launcher-base-distroless:latest"; // Keep in sync with python version used in // https://github.com/GoogleCloudPlatform/DataflowTemplates/blob/main/python/generate_dependencies.sh public static final String BASE_PYTHON_CONTAINER_IMAGE = diff --git a/plugins/templates-maven-plugin/pom.xml b/plugins/templates-maven-plugin/pom.xml index 84202358f2..214373a3b2 100644 --- a/plugins/templates-maven-plugin/pom.xml +++ b/plugins/templates-maven-plugin/pom.xml @@ -36,12 +36,12 @@ - 11 - 11 - 3.3.9 + 17 + 17 + 3.9.9 0.7.6 2.4.0 - 3.6.0 + 3.15.1 diff --git a/plugins/templates-maven-plugin/src/main/java/com/google/cloud/teleport/plugin/maven/TemplatesReleaseFinishMojo.java b/plugins/templates-maven-plugin/src/main/java/com/google/cloud/teleport/plugin/maven/TemplatesReleaseFinishMojo.java index 227734d2e6..083c75aaaf 100644 --- a/plugins/templates-maven-plugin/src/main/java/com/google/cloud/teleport/plugin/maven/TemplatesReleaseFinishMojo.java +++ b/plugins/templates-maven-plugin/src/main/java/com/google/cloud/teleport/plugin/maven/TemplatesReleaseFinishMojo.java @@ -85,7 +85,7 @@ public class TemplatesReleaseFinishMojo extends TemplatesBaseMojo { @Parameter( name = "baseContainerImage", defaultValue = - "gcr.io/dataflow-templates-base/java11-template-launcher-base-distroless:latest", + "gcr.io/dataflow-templates-base/java17-template-launcher-base-distroless:latest", required = false) protected String baseContainerImage; diff --git a/pom.xml b/pom.xml index bfc8983fc6..659b12343d 100644 --- a/pom.xml +++ b/pom.xml @@ -31,13 +31,13 @@ UTF-8 - 11 + 17 1.0-SNAPSHOT 3.2.1 3.11.0 - 3.6.0 + 3.8.1 3.5.0 1.8.0 3.3.0 diff --git a/python/pom.xml b/python/pom.xml index 63996fbf94..f107d5886f 100644 --- a/python/pom.xml +++ b/python/pom.xml @@ -34,8 +34,8 @@ https://github.com/GoogleCloudPlatform/DataflowTemplates - 11 - 11 + 17 + 17 2.57.0 diff --git a/v1/pom.xml b/v1/pom.xml index f329ac49ef..d1123a8380 100644 --- a/v1/pom.xml +++ b/v1/pom.xml @@ -801,7 +801,7 @@ - 11 + 17 - 2.61.0 - 2.61.0 + 2.62.0 + 2.62.0 @@ -66,7 +66,7 @@ 3.3.0 1.13.1 32.0.1-jre - 3.4.0 + 3.4.1 2.1 2.5.3-hadoop3 4.11.0 @@ -77,14 +77,14 @@ 4.13.2 1.6 1.7.36 - 2.0 + 2.2 1.1.10.4 2.40.0 2.21.0 1.1.5 - 2.48.0 + 2.55.0 4.8.0 diff --git a/python/src/main/python/job-builder-server/requirements.txt b/python/src/main/python/job-builder-server/requirements.txt index 4095f3e5bc..ec9e39172c 100644 --- a/python/src/main/python/job-builder-server/requirements.txt +++ b/python/src/main/python/job-builder-server/requirements.txt @@ -27,38 +27,32 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -apache-beam[dataframe,gcp,test,yaml]==2.60.0 \ - --hash=sha256:04644d4021522674b56c32b199c8ca89ee9ffef6eee1b21a29a6b8cd0fdfc16c \ - --hash=sha256:0594dff34776f4929aa24b35b677d5b2688c6e565e6a32921fad7d7c6a4063a0 \ - --hash=sha256:10e4ecd11e7b3c9149e3704b6fc3a5f98ae63c889167681e4e18d9633d34957c \ - --hash=sha256:12f292ee820e37ba0bf47ed54173cb6d15cce24beaa28a676e85ddb3f0a55263 \ - --hash=sha256:239b02a82d8abd0400e8f2316b2b4ee08092c898d3eac36ffa7e3a632612fbb4 \ - --hash=sha256:354f8c058b15608d1a79da55edc4f8fa724fff92269db02a81ccb3dfa82e08a5 \ - --hash=sha256:3728ee7c0e9efcd9e1323ccf5dbebf5d56f7ce0fcc5ec78e63747ec4d7496c44 \ - --hash=sha256:398dc3dc9e7079290548be96102b5bb9179c922534ef166bf22478b6b477b42c \ - --hash=sha256:401593f23e85d5531754ca0fb5bb4e251959dcd1b2864e5a28844004ab1a7231 \ - --hash=sha256:4252bee4ec51effe858aa3ac17ca09520a7dedfe4456a23dd286332e501ea7b9 \ - --hash=sha256:4297dd4d13869f14192ae257527cb8d499273509e6bc166ac92eb0a8ec25f1fe \ - --hash=sha256:447ff21a0eb76dfa78a6164e752a1c1205c055f22145178048cd619dada4e72f \ - --hash=sha256:482ee5caad2244472d7572c555a777e459207770483775d6a694c3ef2f9e5e45 \ - --hash=sha256:4bd24eedddbdd7980e698ab0f588e2e9d641c434f586970a57164259f9ce2db4 \ - --hash=sha256:6062b07b25c766cb8c7a94a64755093a7bc7e7aa0ff39f0f44d13a47d5696619 \ - --hash=sha256:68121213c675ebf23c4d1e0c7f3e60f2db7648e2d7da6323efd62a684b2a64b6 \ - --hash=sha256:7b7e17ff038795f96b64a1e0261338aba2d36857324bd582fedbe05d41542a81 \ - --hash=sha256:8064c7896361a5451371c2d4b03660ba85f673ce00e4c57fed5e355f268dca9b \ - --hash=sha256:83c54241552e35174ad44e90915aebd251beee31f9176a16ec931e8ce65c882d \ - --hash=sha256:863a67bbd0899deefdb1cc7c5b7c03a3f98aae237b0f5fb6311beed2901102e2 \ - --hash=sha256:875f8755842a38db7cda27dfa7f92fe4ef004aaaa49d8b23721193c2010076ef \ - --hash=sha256:951b6a7e49dacef27181f6d1b15db368d9584e0a802dd61cd9fab949ce339ee8 \ - --hash=sha256:aad7ca6f38e7e82bc28ed8473a4649d24249f438543ed6879776d8ef5dc2e743 \ - --hash=sha256:b043748caaeb82655982479b39189f76c1948903230e7cd33057efc66737003f \ - --hash=sha256:ba0404ddf8f95206328993f3db1b50f06d3034bc84c4440c4df4ce86060cee73 \ - --hash=sha256:bcc4142e0465dcfecbec6908896aa4b43ae8d4ca0b3fa88a23fe6d4ee5033b96 \ - --hash=sha256:c7ab3edbac04723bbc3d8c849d824f7bab63c969c14dc0f876d894d06787919a \ - --hash=sha256:f5543ff7c6c64afbded02e9d99b5f142efc12ed5cefefa070a6914b3641d7b02 \ - --hash=sha256:f56d680c2129dcbb5d96439921a1f14a2a072db904fa96ed2c52bef6daa8559c \ - --hash=sha256:fbe467dc7800e257306d43761b61aeaaead8b8ac8ab35d0b296cf4ec9e1d71de \ - --hash=sha256:ffae157ecde933f4dca4c13775ad3c0e7fc846c6b538965bd9222d4bf7ccfa9a +apache-beam[dataframe,gcp,test,yaml]==2.62.0 \ + --hash=sha256:02d33aae5a4cc3acc7a2fb86e3632cdbd240522256778e1da0f6b9192eeef91e \ + --hash=sha256:04c58ef6827142b39a4c95f3403e388646fde8d88e823c7d4f624b45dea459fa \ + --hash=sha256:04e99ef0fd74b645971549a16576f41a7a3c7a5360b67723a906334d70d04be3 \ + --hash=sha256:147491dfde40c9ac0353899fc6632d92d24663c8f9d44ea30157e66752b6f54c \ + --hash=sha256:158bce813662a39e2ee504273cc5fc492779703b8f596ef1a3210a62a5263b10 \ + --hash=sha256:1e8f741de5c66122f5c97f8a6838ab7bfdbe7bbbbdadeef9f91bd0561487c26d \ + --hash=sha256:3489d45fb04d542061af8f59b908e7a0168da5aacded308bb7825fd43f7068c7 \ + --hash=sha256:34d353f5a9aeda4a3ee484907b14e2942b9e8f7f8a112b5a98d69663ed4ef68a \ + --hash=sha256:3d5112494e4e672af404a8cb13dce3c12e3e11e5aaae7d78bc1b2c640f1e8c05 \ + --hash=sha256:5044f2e2608d8e52b8267ec0fba250814388dd97c3ca7107d7cad0897895cbb8 \ + --hash=sha256:5e5584dd4d68e1f1ace4c1775707afb5309852332ecc4975344bcc8a300d7399 \ + --hash=sha256:8843a8306c0548c0224e7f0567de9494552068bd76101b6cc4bef445c3ffa495 \ + --hash=sha256:8b79b8dc2968321d433d8d353a5b4c86c63e3a16cd9aced62c73e8ce3269d3cb \ + --hash=sha256:b158b0c0d8a18e0f0b5c32031b61c51e19b12825312d8c01533c61d65b5fbda4 \ + --hash=sha256:b61f298a43b7672604a4d3c4f3eef413f6c9b55aeadcacd06631d6ccc319aee8 \ + --hash=sha256:b771ad9202816ddd1d887cbe1083b9711b8b3593c0a78f2e85a1d7f5c0adbdac \ + --hash=sha256:b9d97df88b9b9e4585fff5ee09959d76b0ab596bb78ae986fac8c04bf8cc78db \ + --hash=sha256:bc5dd62c005526c82d6ed1ffde7324e5347c1ff417061b5e63c330dc02e9e601 \ + --hash=sha256:c4d5a43bb601520ce5ba30505a1597d2f4f0a02fbf56ca78213565b4c0ae7420 \ + --hash=sha256:c7c1632a29ed785a93e5f9c8bed3e18d962789d06c8acc943f6faf9e24a177b7 \ + --hash=sha256:c947f13bf6b8f7904994a3d846fe71ea2b28991373316c205987a42da8df4084 \ + --hash=sha256:e24db3b37969353f0fdf8c13f2127a391d4483dcb81b2cf6211d37108bd8599a \ + --hash=sha256:e65d11b8ac8eb84cbff56fe2aefb6da6449aee07339755138c8bce3d4d7df206 \ + --hash=sha256:f28d8a79552fceeaaf0ed0b0f2b41b2143e1013745a5847d7defbb4a6ebfe9a1 \ + --hash=sha256:f30e40163a23a64a4469ca2c74674eff7b1b5fcfd49c1461565c4aeda978a096 # via -r python/default_base_yaml_requirements.txt attrs==24.2.0 \ --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ @@ -1072,74 +1066,79 @@ protobuf==4.25.5 \ # grpc-google-iam-v1 # grpcio-status # proto-plus -psycopg2-binary==2.9.10 \ - --hash=sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff \ - --hash=sha256:056470c3dc57904bbf63d6f534988bafc4e970ffd50f6271fc4ee7daad9498a5 \ - --hash=sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f \ - --hash=sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5 \ - --hash=sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0 \ - --hash=sha256:19721ac03892001ee8fdd11507e6a2e01f4e37014def96379411ca99d78aeb2c \ - --hash=sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c \ - --hash=sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341 \ - --hash=sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f \ - --hash=sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7 \ - --hash=sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d \ - --hash=sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007 \ - --hash=sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92 \ - --hash=sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb \ - --hash=sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5 \ - --hash=sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5 \ - --hash=sha256:3216ccf953b3f267691c90c6fe742e45d890d8272326b4a8b20850a03d05b7b8 \ - --hash=sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1 \ - --hash=sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68 \ - --hash=sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73 \ - --hash=sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1 \ - --hash=sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53 \ - --hash=sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d \ - --hash=sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906 \ - --hash=sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0 \ - --hash=sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2 \ - --hash=sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a \ - --hash=sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b \ - --hash=sha256:5c370b1e4975df846b0277b4deba86419ca77dbc25047f535b0bb03d1a544d44 \ - --hash=sha256:6b269105e59ac96aba877c1707c600ae55711d9dcd3fc4b5012e4af68e30c648 \ - --hash=sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7 \ - --hash=sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f \ - --hash=sha256:73aa0e31fa4bb82578f3a6c74a73c273367727de397a7a0f07bd83cbea696baa \ - --hash=sha256:7559bce4b505762d737172556a4e6ea8a9998ecac1e39b5233465093e8cee697 \ - --hash=sha256:79625966e176dc97ddabc142351e0409e28acf4660b88d1cf6adb876d20c490d \ - --hash=sha256:7a813c8bdbaaaab1f078014b9b0b13f5de757e2b5d9be6403639b298a04d218b \ - --hash=sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526 \ - --hash=sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4 \ - --hash=sha256:7f5d859928e635fa3ce3477704acee0f667b3a3d3e4bb109f2b18d4005f38287 \ - --hash=sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e \ - --hash=sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673 \ - --hash=sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0 \ - --hash=sha256:8aabf1c1a04584c168984ac678a668094d831f152859d06e055288fa515e4d30 \ - --hash=sha256:8aecc5e80c63f7459a1a2ab2c64df952051df196294d9f739933a9f6687e86b3 \ - --hash=sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e \ - --hash=sha256:8de718c0e1c4b982a54b41779667242bc630b2197948405b7bd8ce16bcecac92 \ - --hash=sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a \ - --hash=sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c \ - --hash=sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8 \ - --hash=sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909 \ - --hash=sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47 \ - --hash=sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864 \ - --hash=sha256:d00924255d7fc916ef66e4bf22f354a940c67179ad3fd7067d7a0a9c84d2fbfc \ - --hash=sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00 \ - --hash=sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb \ - --hash=sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539 \ - --hash=sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b \ - --hash=sha256:e8b58f0a96e7a1e341fc894f62c1177a7c83febebb5ff9123b579418fdc8a481 \ - --hash=sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5 \ - --hash=sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4 \ - --hash=sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64 \ - --hash=sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392 \ - --hash=sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4 \ - --hash=sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1 \ - --hash=sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1 \ - --hash=sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567 \ - --hash=sha256:ffe8ed017e4ed70f68b7b371d84b7d4a790368db9203dfc2d222febd3a9c8863 +psycopg2-binary==2.9.9 \ + --hash=sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9 \ + --hash=sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77 \ + --hash=sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e \ + --hash=sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84 \ + --hash=sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3 \ + --hash=sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2 \ + --hash=sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67 \ + --hash=sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876 \ + --hash=sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152 \ + --hash=sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f \ + --hash=sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a \ + --hash=sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6 \ + --hash=sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503 \ + --hash=sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f \ + --hash=sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493 \ + --hash=sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996 \ + --hash=sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f \ + --hash=sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e \ + --hash=sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59 \ + --hash=sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94 \ + --hash=sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7 \ + --hash=sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682 \ + --hash=sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420 \ + --hash=sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae \ + --hash=sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291 \ + --hash=sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe \ + --hash=sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980 \ + --hash=sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93 \ + --hash=sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692 \ + --hash=sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119 \ + --hash=sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716 \ + --hash=sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472 \ + --hash=sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b \ + --hash=sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2 \ + --hash=sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc \ + --hash=sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c \ + --hash=sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5 \ + --hash=sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab \ + --hash=sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984 \ + --hash=sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9 \ + --hash=sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf \ + --hash=sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0 \ + --hash=sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f \ + --hash=sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212 \ + --hash=sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb \ + --hash=sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be \ + --hash=sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90 \ + --hash=sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041 \ + --hash=sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7 \ + --hash=sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860 \ + --hash=sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d \ + --hash=sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245 \ + --hash=sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27 \ + --hash=sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417 \ + --hash=sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359 \ + --hash=sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202 \ + --hash=sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0 \ + --hash=sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7 \ + --hash=sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba \ + --hash=sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1 \ + --hash=sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd \ + --hash=sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07 \ + --hash=sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98 \ + --hash=sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55 \ + --hash=sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d \ + --hash=sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972 \ + --hash=sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f \ + --hash=sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e \ + --hash=sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26 \ + --hash=sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957 \ + --hash=sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53 \ + --hash=sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52 # via apache-beam pyarrow==16.1.0 \ --hash=sha256:06ebccb6f8cb7357de85f60d5da50e83507954af617d7b05f48af1621d331c9a \ @@ -1820,7 +1819,9 @@ six==1.16.0 \ sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 - # via hypothesis + # via + # apache-beam + # hypothesis sqlalchemy==2.0.36 \ --hash=sha256:03e08af7a5f9386a43919eda9de33ffda16b44eb11f3b313e6822243770e9763 \ --hash=sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436 \ diff --git a/python/src/main/python/streaming-llm/requirements.txt b/python/src/main/python/streaming-llm/requirements.txt index f1e5f9da90..0af80d21db 100644 --- a/python/src/main/python/streaming-llm/requirements.txt +++ b/python/src/main/python/streaming-llm/requirements.txt @@ -27,38 +27,32 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -apache-beam[gcp]==2.60.0 \ - --hash=sha256:02239d5290f79bf22c651d15d8e8f667da19dcca32922a7cd0acb5cfd78c03ac \ - --hash=sha256:0764d1f83b6010e1712d783c5c9bd46c4aa1e8064f00480eb53ef59a64573adb \ - --hash=sha256:0e834fc077111ad86610f0a69e4ea76f58874f557b9fc08a13476ab03689a0e6 \ - --hash=sha256:116950f1cf4f5e3769a5f6b5b97b579c7bea71a59dfc82a335d7d8765ca0c655 \ - --hash=sha256:1c7a90cebddd5175077bab59cfb1909e5c8a5341c59ea2a7d7622ecd3ac1d829 \ - --hash=sha256:269d85a44f32fd279d80b27b0ef8a20e38d2715e5c24d009d90363c4b6b54c86 \ - --hash=sha256:29294cb3b9033d92c0f1ef4474f42ec45c8dc3eefdb89f6d30a2337ca43452a1 \ - --hash=sha256:3311cd1ef7848df444c75a2f502bd04b40f6e565c7ca0044da8b9362d4bdca73 \ - --hash=sha256:39cae208c16929a8bd2b6d31011de553dd458e88acfee9649dbd72c1617d9c39 \ - --hash=sha256:4002abe6c0b872dfba99d4785211d15ec368a0c6f67fe989db5342fba022e260 \ - --hash=sha256:55e4cbf0f8fc2a759addfd6e58913383c54631c933ee04e280aad058f6cf744c \ - --hash=sha256:6324eb39bfaabb4dab6e4210f95d84811c88dcad6577fa6e6e5cc560ba18bea7 \ - --hash=sha256:6405ad1612b232acfad2b8def68db7d54cd4b16bd4fdca121bc8bd03c6263fe9 \ - --hash=sha256:6678d5c9408be842a7f87842925a5468423bb3eed8182c99d34a95541ad0d2b2 \ - --hash=sha256:7baea8eb6b021d794552316e8cdccb681d5a7a811727b00fb9d51683e03f3a7c \ - --hash=sha256:8d8e38068783ad3ecab0e2beaab389ff4796375604c9104f7b1e19945e496970 \ - --hash=sha256:9b33a4a168a895dc5c18b1a4d2b9176f76cb3109bcc8c68cce3573f72e490e6d \ - --hash=sha256:a97f302b434df44d6f3dcb241c475ebff445f34459425d7f3bbb982011afad81 \ - --hash=sha256:abbc1c7b23e340c5091b791545079c14d32ecae0cb7c840f762e9abe6540fe2b \ - --hash=sha256:b3a90d5f9c453442ceccc95c67c918fa28f567759f718d9064ac75ecb985b77e \ - --hash=sha256:b428dd82522ad926c2172e8741723b66a6662c9033c744b25fd069e1c8e5e1db \ - --hash=sha256:b9cfa06daefd356cc318140ad9e0dc66fdbaa93e5a3e59f187d7c74252072fe9 \ - --hash=sha256:bf85fe978889e39b8ac3e52f22ebe8169d48460b637342ba3a8bd2024c3b5ef4 \ - --hash=sha256:c9fbbc16d3575559f1c2259d00adf96a2eb0e9a2f708f65d32089e85d2be0239 \ - --hash=sha256:db2e7e51565d1b29ce9e599542e3ee716bc36745d9c1253377c9690cfe764d0e \ - --hash=sha256:e281ca1e447ee4858984a3c72f1846ec867002e0a31c874b18c440604f745245 \ - --hash=sha256:ea315ec12637c5ca474f3bf7f8afabe9981cf6f1a67ddfff8bef1c8f035b228c \ - --hash=sha256:eab5b461936751d849decba594c1c0a081492cfeca3fe241eda6bc51816be9b1 \ - --hash=sha256:ecf74d123ddd10a114ca47f7b9c74b354121c1c1911da2b05e0e964e86ecbac8 \ - --hash=sha256:f1b7c019af38b4f1ff899824dbf8380a6e7245c158814546b62e8b4ab7a1d483 \ - --hash=sha256:fc0788f7313762eaedffbda4e8139e8a65b658a84dc577a5a4e106e4b0a21556 +apache-beam[gcp]==2.62.0 \ + --hash=sha256:02d33aae5a4cc3acc7a2fb86e3632cdbd240522256778e1da0f6b9192eeef91e \ + --hash=sha256:04c58ef6827142b39a4c95f3403e388646fde8d88e823c7d4f624b45dea459fa \ + --hash=sha256:04e99ef0fd74b645971549a16576f41a7a3c7a5360b67723a906334d70d04be3 \ + --hash=sha256:147491dfde40c9ac0353899fc6632d92d24663c8f9d44ea30157e66752b6f54c \ + --hash=sha256:158bce813662a39e2ee504273cc5fc492779703b8f596ef1a3210a62a5263b10 \ + --hash=sha256:1e8f741de5c66122f5c97f8a6838ab7bfdbe7bbbbdadeef9f91bd0561487c26d \ + --hash=sha256:3489d45fb04d542061af8f59b908e7a0168da5aacded308bb7825fd43f7068c7 \ + --hash=sha256:34d353f5a9aeda4a3ee484907b14e2942b9e8f7f8a112b5a98d69663ed4ef68a \ + --hash=sha256:3d5112494e4e672af404a8cb13dce3c12e3e11e5aaae7d78bc1b2c640f1e8c05 \ + --hash=sha256:5044f2e2608d8e52b8267ec0fba250814388dd97c3ca7107d7cad0897895cbb8 \ + --hash=sha256:5e5584dd4d68e1f1ace4c1775707afb5309852332ecc4975344bcc8a300d7399 \ + --hash=sha256:8843a8306c0548c0224e7f0567de9494552068bd76101b6cc4bef445c3ffa495 \ + --hash=sha256:8b79b8dc2968321d433d8d353a5b4c86c63e3a16cd9aced62c73e8ce3269d3cb \ + --hash=sha256:b158b0c0d8a18e0f0b5c32031b61c51e19b12825312d8c01533c61d65b5fbda4 \ + --hash=sha256:b61f298a43b7672604a4d3c4f3eef413f6c9b55aeadcacd06631d6ccc319aee8 \ + --hash=sha256:b771ad9202816ddd1d887cbe1083b9711b8b3593c0a78f2e85a1d7f5c0adbdac \ + --hash=sha256:b9d97df88b9b9e4585fff5ee09959d76b0ab596bb78ae986fac8c04bf8cc78db \ + --hash=sha256:bc5dd62c005526c82d6ed1ffde7324e5347c1ff417061b5e63c330dc02e9e601 \ + --hash=sha256:c4d5a43bb601520ce5ba30505a1597d2f4f0a02fbf56ca78213565b4c0ae7420 \ + --hash=sha256:c7c1632a29ed785a93e5f9c8bed3e18d962789d06c8acc943f6faf9e24a177b7 \ + --hash=sha256:c947f13bf6b8f7904994a3d846fe71ea2b28991373316c205987a42da8df4084 \ + --hash=sha256:e24db3b37969353f0fdf8c13f2127a391d4483dcb81b2cf6211d37108bd8599a \ + --hash=sha256:e65d11b8ac8eb84cbff56fe2aefb6da6449aee07339755138c8bce3d4d7df206 \ + --hash=sha256:f28d8a79552fceeaaf0ed0b0f2b41b2143e1013745a5847d7defbb4a6ebfe9a1 \ + --hash=sha256:f30e40163a23a64a4469ca2c74674eff7b1b5fcfd49c1461565c4aeda978a096 # via -r python/../python/src/main/python/streaming-llm/base_requirements.txt attrs==24.2.0 \ --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ @@ -1359,6 +1353,7 @@ pyyaml==6.0.2 \ --hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \ --hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4 # via + # apache-beam # huggingface-hub # transformers redis==5.0.8 \ @@ -1762,6 +1757,10 @@ six==1.16.0 \ # hdfs # oauth2client # python-dateutil +sortedcontainers==2.4.0 \ + --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ + --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 + # via apache-beam sqlparse==0.5.1 \ --hash=sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4 \ --hash=sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e diff --git a/python/src/main/python/word-count-python/requirements.txt b/python/src/main/python/word-count-python/requirements.txt index a691f40a0f..a9cedcb360 100644 --- a/python/src/main/python/word-count-python/requirements.txt +++ b/python/src/main/python/word-count-python/requirements.txt @@ -27,38 +27,32 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -apache-beam[gcp]==2.60.0 \ - --hash=sha256:04644d4021522674b56c32b199c8ca89ee9ffef6eee1b21a29a6b8cd0fdfc16c \ - --hash=sha256:0594dff34776f4929aa24b35b677d5b2688c6e565e6a32921fad7d7c6a4063a0 \ - --hash=sha256:10e4ecd11e7b3c9149e3704b6fc3a5f98ae63c889167681e4e18d9633d34957c \ - --hash=sha256:12f292ee820e37ba0bf47ed54173cb6d15cce24beaa28a676e85ddb3f0a55263 \ - --hash=sha256:239b02a82d8abd0400e8f2316b2b4ee08092c898d3eac36ffa7e3a632612fbb4 \ - --hash=sha256:354f8c058b15608d1a79da55edc4f8fa724fff92269db02a81ccb3dfa82e08a5 \ - --hash=sha256:3728ee7c0e9efcd9e1323ccf5dbebf5d56f7ce0fcc5ec78e63747ec4d7496c44 \ - --hash=sha256:398dc3dc9e7079290548be96102b5bb9179c922534ef166bf22478b6b477b42c \ - --hash=sha256:401593f23e85d5531754ca0fb5bb4e251959dcd1b2864e5a28844004ab1a7231 \ - --hash=sha256:4252bee4ec51effe858aa3ac17ca09520a7dedfe4456a23dd286332e501ea7b9 \ - --hash=sha256:4297dd4d13869f14192ae257527cb8d499273509e6bc166ac92eb0a8ec25f1fe \ - --hash=sha256:447ff21a0eb76dfa78a6164e752a1c1205c055f22145178048cd619dada4e72f \ - --hash=sha256:482ee5caad2244472d7572c555a777e459207770483775d6a694c3ef2f9e5e45 \ - --hash=sha256:4bd24eedddbdd7980e698ab0f588e2e9d641c434f586970a57164259f9ce2db4 \ - --hash=sha256:6062b07b25c766cb8c7a94a64755093a7bc7e7aa0ff39f0f44d13a47d5696619 \ - --hash=sha256:68121213c675ebf23c4d1e0c7f3e60f2db7648e2d7da6323efd62a684b2a64b6 \ - --hash=sha256:7b7e17ff038795f96b64a1e0261338aba2d36857324bd582fedbe05d41542a81 \ - --hash=sha256:8064c7896361a5451371c2d4b03660ba85f673ce00e4c57fed5e355f268dca9b \ - --hash=sha256:83c54241552e35174ad44e90915aebd251beee31f9176a16ec931e8ce65c882d \ - --hash=sha256:863a67bbd0899deefdb1cc7c5b7c03a3f98aae237b0f5fb6311beed2901102e2 \ - --hash=sha256:875f8755842a38db7cda27dfa7f92fe4ef004aaaa49d8b23721193c2010076ef \ - --hash=sha256:951b6a7e49dacef27181f6d1b15db368d9584e0a802dd61cd9fab949ce339ee8 \ - --hash=sha256:aad7ca6f38e7e82bc28ed8473a4649d24249f438543ed6879776d8ef5dc2e743 \ - --hash=sha256:b043748caaeb82655982479b39189f76c1948903230e7cd33057efc66737003f \ - --hash=sha256:ba0404ddf8f95206328993f3db1b50f06d3034bc84c4440c4df4ce86060cee73 \ - --hash=sha256:bcc4142e0465dcfecbec6908896aa4b43ae8d4ca0b3fa88a23fe6d4ee5033b96 \ - --hash=sha256:c7ab3edbac04723bbc3d8c849d824f7bab63c969c14dc0f876d894d06787919a \ - --hash=sha256:f5543ff7c6c64afbded02e9d99b5f142efc12ed5cefefa070a6914b3641d7b02 \ - --hash=sha256:f56d680c2129dcbb5d96439921a1f14a2a072db904fa96ed2c52bef6daa8559c \ - --hash=sha256:fbe467dc7800e257306d43761b61aeaaead8b8ac8ab35d0b296cf4ec9e1d71de \ - --hash=sha256:ffae157ecde933f4dca4c13775ad3c0e7fc846c6b538965bd9222d4bf7ccfa9a +apache-beam[gcp]==2.62.0 \ + --hash=sha256:02d33aae5a4cc3acc7a2fb86e3632cdbd240522256778e1da0f6b9192eeef91e \ + --hash=sha256:04c58ef6827142b39a4c95f3403e388646fde8d88e823c7d4f624b45dea459fa \ + --hash=sha256:04e99ef0fd74b645971549a16576f41a7a3c7a5360b67723a906334d70d04be3 \ + --hash=sha256:147491dfde40c9ac0353899fc6632d92d24663c8f9d44ea30157e66752b6f54c \ + --hash=sha256:158bce813662a39e2ee504273cc5fc492779703b8f596ef1a3210a62a5263b10 \ + --hash=sha256:1e8f741de5c66122f5c97f8a6838ab7bfdbe7bbbbdadeef9f91bd0561487c26d \ + --hash=sha256:3489d45fb04d542061af8f59b908e7a0168da5aacded308bb7825fd43f7068c7 \ + --hash=sha256:34d353f5a9aeda4a3ee484907b14e2942b9e8f7f8a112b5a98d69663ed4ef68a \ + --hash=sha256:3d5112494e4e672af404a8cb13dce3c12e3e11e5aaae7d78bc1b2c640f1e8c05 \ + --hash=sha256:5044f2e2608d8e52b8267ec0fba250814388dd97c3ca7107d7cad0897895cbb8 \ + --hash=sha256:5e5584dd4d68e1f1ace4c1775707afb5309852332ecc4975344bcc8a300d7399 \ + --hash=sha256:8843a8306c0548c0224e7f0567de9494552068bd76101b6cc4bef445c3ffa495 \ + --hash=sha256:8b79b8dc2968321d433d8d353a5b4c86c63e3a16cd9aced62c73e8ce3269d3cb \ + --hash=sha256:b158b0c0d8a18e0f0b5c32031b61c51e19b12825312d8c01533c61d65b5fbda4 \ + --hash=sha256:b61f298a43b7672604a4d3c4f3eef413f6c9b55aeadcacd06631d6ccc319aee8 \ + --hash=sha256:b771ad9202816ddd1d887cbe1083b9711b8b3593c0a78f2e85a1d7f5c0adbdac \ + --hash=sha256:b9d97df88b9b9e4585fff5ee09959d76b0ab596bb78ae986fac8c04bf8cc78db \ + --hash=sha256:bc5dd62c005526c82d6ed1ffde7324e5347c1ff417061b5e63c330dc02e9e601 \ + --hash=sha256:c4d5a43bb601520ce5ba30505a1597d2f4f0a02fbf56ca78213565b4c0ae7420 \ + --hash=sha256:c7c1632a29ed785a93e5f9c8bed3e18d962789d06c8acc943f6faf9e24a177b7 \ + --hash=sha256:c947f13bf6b8f7904994a3d846fe71ea2b28991373316c205987a42da8df4084 \ + --hash=sha256:e24db3b37969353f0fdf8c13f2127a391d4483dcb81b2cf6211d37108bd8599a \ + --hash=sha256:e65d11b8ac8eb84cbff56fe2aefb6da6449aee07339755138c8bce3d4d7df206 \ + --hash=sha256:f28d8a79552fceeaaf0ed0b0f2b41b2143e1013745a5847d7defbb4a6ebfe9a1 \ + --hash=sha256:f30e40163a23a64a4469ca2c74674eff7b1b5fcfd49c1461565c4aeda978a096 # via -r python/default_base_python_requirements.txt attrs==24.2.0 \ --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ @@ -1084,6 +1078,61 @@ pytz==2024.2 \ --hash=sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a \ --hash=sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725 # via apache-beam +pyyaml==6.0.2 \ + --hash=sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff \ + --hash=sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48 \ + --hash=sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086 \ + --hash=sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e \ + --hash=sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133 \ + --hash=sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5 \ + --hash=sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484 \ + --hash=sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee \ + --hash=sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5 \ + --hash=sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68 \ + --hash=sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a \ + --hash=sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf \ + --hash=sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99 \ + --hash=sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8 \ + --hash=sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85 \ + --hash=sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19 \ + --hash=sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc \ + --hash=sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a \ + --hash=sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1 \ + --hash=sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317 \ + --hash=sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c \ + --hash=sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631 \ + --hash=sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d \ + --hash=sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652 \ + --hash=sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5 \ + --hash=sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e \ + --hash=sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b \ + --hash=sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8 \ + --hash=sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476 \ + --hash=sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706 \ + --hash=sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563 \ + --hash=sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237 \ + --hash=sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b \ + --hash=sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083 \ + --hash=sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180 \ + --hash=sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425 \ + --hash=sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e \ + --hash=sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f \ + --hash=sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725 \ + --hash=sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183 \ + --hash=sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab \ + --hash=sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774 \ + --hash=sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725 \ + --hash=sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e \ + --hash=sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5 \ + --hash=sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d \ + --hash=sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290 \ + --hash=sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44 \ + --hash=sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed \ + --hash=sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4 \ + --hash=sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba \ + --hash=sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12 \ + --hash=sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4 + # via apache-beam redis==5.1.1 \ --hash=sha256:f6c997521fedbae53387307c5d0bf784d9acc28d9f1d058abeac566ec4dbed72 \ --hash=sha256:f8ea06b7482a668c6475ae202ed8d9bcaa409f6e87fb77ed1043d912afd62e24 @@ -1369,6 +1418,10 @@ six==1.16.0 \ # hdfs # oauth2client # python-dateutil +sortedcontainers==2.4.0 \ + --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ + --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 + # via apache-beam sqlparse==0.5.1 \ --hash=sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4 \ --hash=sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e diff --git a/python/src/main/python/yaml-template/requirements.txt b/python/src/main/python/yaml-template/requirements.txt index 4095f3e5bc..ec9e39172c 100644 --- a/python/src/main/python/yaml-template/requirements.txt +++ b/python/src/main/python/yaml-template/requirements.txt @@ -27,38 +27,32 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -apache-beam[dataframe,gcp,test,yaml]==2.60.0 \ - --hash=sha256:04644d4021522674b56c32b199c8ca89ee9ffef6eee1b21a29a6b8cd0fdfc16c \ - --hash=sha256:0594dff34776f4929aa24b35b677d5b2688c6e565e6a32921fad7d7c6a4063a0 \ - --hash=sha256:10e4ecd11e7b3c9149e3704b6fc3a5f98ae63c889167681e4e18d9633d34957c \ - --hash=sha256:12f292ee820e37ba0bf47ed54173cb6d15cce24beaa28a676e85ddb3f0a55263 \ - --hash=sha256:239b02a82d8abd0400e8f2316b2b4ee08092c898d3eac36ffa7e3a632612fbb4 \ - --hash=sha256:354f8c058b15608d1a79da55edc4f8fa724fff92269db02a81ccb3dfa82e08a5 \ - --hash=sha256:3728ee7c0e9efcd9e1323ccf5dbebf5d56f7ce0fcc5ec78e63747ec4d7496c44 \ - --hash=sha256:398dc3dc9e7079290548be96102b5bb9179c922534ef166bf22478b6b477b42c \ - --hash=sha256:401593f23e85d5531754ca0fb5bb4e251959dcd1b2864e5a28844004ab1a7231 \ - --hash=sha256:4252bee4ec51effe858aa3ac17ca09520a7dedfe4456a23dd286332e501ea7b9 \ - --hash=sha256:4297dd4d13869f14192ae257527cb8d499273509e6bc166ac92eb0a8ec25f1fe \ - --hash=sha256:447ff21a0eb76dfa78a6164e752a1c1205c055f22145178048cd619dada4e72f \ - --hash=sha256:482ee5caad2244472d7572c555a777e459207770483775d6a694c3ef2f9e5e45 \ - --hash=sha256:4bd24eedddbdd7980e698ab0f588e2e9d641c434f586970a57164259f9ce2db4 \ - --hash=sha256:6062b07b25c766cb8c7a94a64755093a7bc7e7aa0ff39f0f44d13a47d5696619 \ - --hash=sha256:68121213c675ebf23c4d1e0c7f3e60f2db7648e2d7da6323efd62a684b2a64b6 \ - --hash=sha256:7b7e17ff038795f96b64a1e0261338aba2d36857324bd582fedbe05d41542a81 \ - --hash=sha256:8064c7896361a5451371c2d4b03660ba85f673ce00e4c57fed5e355f268dca9b \ - --hash=sha256:83c54241552e35174ad44e90915aebd251beee31f9176a16ec931e8ce65c882d \ - --hash=sha256:863a67bbd0899deefdb1cc7c5b7c03a3f98aae237b0f5fb6311beed2901102e2 \ - --hash=sha256:875f8755842a38db7cda27dfa7f92fe4ef004aaaa49d8b23721193c2010076ef \ - --hash=sha256:951b6a7e49dacef27181f6d1b15db368d9584e0a802dd61cd9fab949ce339ee8 \ - --hash=sha256:aad7ca6f38e7e82bc28ed8473a4649d24249f438543ed6879776d8ef5dc2e743 \ - --hash=sha256:b043748caaeb82655982479b39189f76c1948903230e7cd33057efc66737003f \ - --hash=sha256:ba0404ddf8f95206328993f3db1b50f06d3034bc84c4440c4df4ce86060cee73 \ - --hash=sha256:bcc4142e0465dcfecbec6908896aa4b43ae8d4ca0b3fa88a23fe6d4ee5033b96 \ - --hash=sha256:c7ab3edbac04723bbc3d8c849d824f7bab63c969c14dc0f876d894d06787919a \ - --hash=sha256:f5543ff7c6c64afbded02e9d99b5f142efc12ed5cefefa070a6914b3641d7b02 \ - --hash=sha256:f56d680c2129dcbb5d96439921a1f14a2a072db904fa96ed2c52bef6daa8559c \ - --hash=sha256:fbe467dc7800e257306d43761b61aeaaead8b8ac8ab35d0b296cf4ec9e1d71de \ - --hash=sha256:ffae157ecde933f4dca4c13775ad3c0e7fc846c6b538965bd9222d4bf7ccfa9a +apache-beam[dataframe,gcp,test,yaml]==2.62.0 \ + --hash=sha256:02d33aae5a4cc3acc7a2fb86e3632cdbd240522256778e1da0f6b9192eeef91e \ + --hash=sha256:04c58ef6827142b39a4c95f3403e388646fde8d88e823c7d4f624b45dea459fa \ + --hash=sha256:04e99ef0fd74b645971549a16576f41a7a3c7a5360b67723a906334d70d04be3 \ + --hash=sha256:147491dfde40c9ac0353899fc6632d92d24663c8f9d44ea30157e66752b6f54c \ + --hash=sha256:158bce813662a39e2ee504273cc5fc492779703b8f596ef1a3210a62a5263b10 \ + --hash=sha256:1e8f741de5c66122f5c97f8a6838ab7bfdbe7bbbbdadeef9f91bd0561487c26d \ + --hash=sha256:3489d45fb04d542061af8f59b908e7a0168da5aacded308bb7825fd43f7068c7 \ + --hash=sha256:34d353f5a9aeda4a3ee484907b14e2942b9e8f7f8a112b5a98d69663ed4ef68a \ + --hash=sha256:3d5112494e4e672af404a8cb13dce3c12e3e11e5aaae7d78bc1b2c640f1e8c05 \ + --hash=sha256:5044f2e2608d8e52b8267ec0fba250814388dd97c3ca7107d7cad0897895cbb8 \ + --hash=sha256:5e5584dd4d68e1f1ace4c1775707afb5309852332ecc4975344bcc8a300d7399 \ + --hash=sha256:8843a8306c0548c0224e7f0567de9494552068bd76101b6cc4bef445c3ffa495 \ + --hash=sha256:8b79b8dc2968321d433d8d353a5b4c86c63e3a16cd9aced62c73e8ce3269d3cb \ + --hash=sha256:b158b0c0d8a18e0f0b5c32031b61c51e19b12825312d8c01533c61d65b5fbda4 \ + --hash=sha256:b61f298a43b7672604a4d3c4f3eef413f6c9b55aeadcacd06631d6ccc319aee8 \ + --hash=sha256:b771ad9202816ddd1d887cbe1083b9711b8b3593c0a78f2e85a1d7f5c0adbdac \ + --hash=sha256:b9d97df88b9b9e4585fff5ee09959d76b0ab596bb78ae986fac8c04bf8cc78db \ + --hash=sha256:bc5dd62c005526c82d6ed1ffde7324e5347c1ff417061b5e63c330dc02e9e601 \ + --hash=sha256:c4d5a43bb601520ce5ba30505a1597d2f4f0a02fbf56ca78213565b4c0ae7420 \ + --hash=sha256:c7c1632a29ed785a93e5f9c8bed3e18d962789d06c8acc943f6faf9e24a177b7 \ + --hash=sha256:c947f13bf6b8f7904994a3d846fe71ea2b28991373316c205987a42da8df4084 \ + --hash=sha256:e24db3b37969353f0fdf8c13f2127a391d4483dcb81b2cf6211d37108bd8599a \ + --hash=sha256:e65d11b8ac8eb84cbff56fe2aefb6da6449aee07339755138c8bce3d4d7df206 \ + --hash=sha256:f28d8a79552fceeaaf0ed0b0f2b41b2143e1013745a5847d7defbb4a6ebfe9a1 \ + --hash=sha256:f30e40163a23a64a4469ca2c74674eff7b1b5fcfd49c1461565c4aeda978a096 # via -r python/default_base_yaml_requirements.txt attrs==24.2.0 \ --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ @@ -1072,74 +1066,79 @@ protobuf==4.25.5 \ # grpc-google-iam-v1 # grpcio-status # proto-plus -psycopg2-binary==2.9.10 \ - --hash=sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff \ - --hash=sha256:056470c3dc57904bbf63d6f534988bafc4e970ffd50f6271fc4ee7daad9498a5 \ - --hash=sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f \ - --hash=sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5 \ - --hash=sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0 \ - --hash=sha256:19721ac03892001ee8fdd11507e6a2e01f4e37014def96379411ca99d78aeb2c \ - --hash=sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c \ - --hash=sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341 \ - --hash=sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f \ - --hash=sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7 \ - --hash=sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d \ - --hash=sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007 \ - --hash=sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92 \ - --hash=sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb \ - --hash=sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5 \ - --hash=sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5 \ - --hash=sha256:3216ccf953b3f267691c90c6fe742e45d890d8272326b4a8b20850a03d05b7b8 \ - --hash=sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1 \ - --hash=sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68 \ - --hash=sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73 \ - --hash=sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1 \ - --hash=sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53 \ - --hash=sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d \ - --hash=sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906 \ - --hash=sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0 \ - --hash=sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2 \ - --hash=sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a \ - --hash=sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b \ - --hash=sha256:5c370b1e4975df846b0277b4deba86419ca77dbc25047f535b0bb03d1a544d44 \ - --hash=sha256:6b269105e59ac96aba877c1707c600ae55711d9dcd3fc4b5012e4af68e30c648 \ - --hash=sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7 \ - --hash=sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f \ - --hash=sha256:73aa0e31fa4bb82578f3a6c74a73c273367727de397a7a0f07bd83cbea696baa \ - --hash=sha256:7559bce4b505762d737172556a4e6ea8a9998ecac1e39b5233465093e8cee697 \ - --hash=sha256:79625966e176dc97ddabc142351e0409e28acf4660b88d1cf6adb876d20c490d \ - --hash=sha256:7a813c8bdbaaaab1f078014b9b0b13f5de757e2b5d9be6403639b298a04d218b \ - --hash=sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526 \ - --hash=sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4 \ - --hash=sha256:7f5d859928e635fa3ce3477704acee0f667b3a3d3e4bb109f2b18d4005f38287 \ - --hash=sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e \ - --hash=sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673 \ - --hash=sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0 \ - --hash=sha256:8aabf1c1a04584c168984ac678a668094d831f152859d06e055288fa515e4d30 \ - --hash=sha256:8aecc5e80c63f7459a1a2ab2c64df952051df196294d9f739933a9f6687e86b3 \ - --hash=sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e \ - --hash=sha256:8de718c0e1c4b982a54b41779667242bc630b2197948405b7bd8ce16bcecac92 \ - --hash=sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a \ - --hash=sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c \ - --hash=sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8 \ - --hash=sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909 \ - --hash=sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47 \ - --hash=sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864 \ - --hash=sha256:d00924255d7fc916ef66e4bf22f354a940c67179ad3fd7067d7a0a9c84d2fbfc \ - --hash=sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00 \ - --hash=sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb \ - --hash=sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539 \ - --hash=sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b \ - --hash=sha256:e8b58f0a96e7a1e341fc894f62c1177a7c83febebb5ff9123b579418fdc8a481 \ - --hash=sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5 \ - --hash=sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4 \ - --hash=sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64 \ - --hash=sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392 \ - --hash=sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4 \ - --hash=sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1 \ - --hash=sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1 \ - --hash=sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567 \ - --hash=sha256:ffe8ed017e4ed70f68b7b371d84b7d4a790368db9203dfc2d222febd3a9c8863 +psycopg2-binary==2.9.9 \ + --hash=sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9 \ + --hash=sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77 \ + --hash=sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e \ + --hash=sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84 \ + --hash=sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3 \ + --hash=sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2 \ + --hash=sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67 \ + --hash=sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876 \ + --hash=sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152 \ + --hash=sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f \ + --hash=sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a \ + --hash=sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6 \ + --hash=sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503 \ + --hash=sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f \ + --hash=sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493 \ + --hash=sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996 \ + --hash=sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f \ + --hash=sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e \ + --hash=sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59 \ + --hash=sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94 \ + --hash=sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7 \ + --hash=sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682 \ + --hash=sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420 \ + --hash=sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae \ + --hash=sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291 \ + --hash=sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe \ + --hash=sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980 \ + --hash=sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93 \ + --hash=sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692 \ + --hash=sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119 \ + --hash=sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716 \ + --hash=sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472 \ + --hash=sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b \ + --hash=sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2 \ + --hash=sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc \ + --hash=sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c \ + --hash=sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5 \ + --hash=sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab \ + --hash=sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984 \ + --hash=sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9 \ + --hash=sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf \ + --hash=sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0 \ + --hash=sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f \ + --hash=sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212 \ + --hash=sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb \ + --hash=sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be \ + --hash=sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90 \ + --hash=sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041 \ + --hash=sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7 \ + --hash=sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860 \ + --hash=sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d \ + --hash=sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245 \ + --hash=sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27 \ + --hash=sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417 \ + --hash=sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359 \ + --hash=sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202 \ + --hash=sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0 \ + --hash=sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7 \ + --hash=sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba \ + --hash=sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1 \ + --hash=sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd \ + --hash=sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07 \ + --hash=sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98 \ + --hash=sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55 \ + --hash=sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d \ + --hash=sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972 \ + --hash=sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f \ + --hash=sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e \ + --hash=sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26 \ + --hash=sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957 \ + --hash=sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53 \ + --hash=sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52 # via apache-beam pyarrow==16.1.0 \ --hash=sha256:06ebccb6f8cb7357de85f60d5da50e83507954af617d7b05f48af1621d331c9a \ @@ -1820,7 +1819,9 @@ six==1.16.0 \ sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 - # via hypothesis + # via + # apache-beam + # hypothesis sqlalchemy==2.0.36 \ --hash=sha256:03e08af7a5f9386a43919eda9de33ffda16b44eb11f3b313e6822243770e9763 \ --hash=sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436 \ diff --git a/v2/googlecloud-to-elasticsearch/src/main/resources/requirements.txt b/v2/googlecloud-to-elasticsearch/src/main/resources/requirements.txt index 4095f3e5bc..ec9e39172c 100644 --- a/v2/googlecloud-to-elasticsearch/src/main/resources/requirements.txt +++ b/v2/googlecloud-to-elasticsearch/src/main/resources/requirements.txt @@ -27,38 +27,32 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -apache-beam[dataframe,gcp,test,yaml]==2.60.0 \ - --hash=sha256:04644d4021522674b56c32b199c8ca89ee9ffef6eee1b21a29a6b8cd0fdfc16c \ - --hash=sha256:0594dff34776f4929aa24b35b677d5b2688c6e565e6a32921fad7d7c6a4063a0 \ - --hash=sha256:10e4ecd11e7b3c9149e3704b6fc3a5f98ae63c889167681e4e18d9633d34957c \ - --hash=sha256:12f292ee820e37ba0bf47ed54173cb6d15cce24beaa28a676e85ddb3f0a55263 \ - --hash=sha256:239b02a82d8abd0400e8f2316b2b4ee08092c898d3eac36ffa7e3a632612fbb4 \ - --hash=sha256:354f8c058b15608d1a79da55edc4f8fa724fff92269db02a81ccb3dfa82e08a5 \ - --hash=sha256:3728ee7c0e9efcd9e1323ccf5dbebf5d56f7ce0fcc5ec78e63747ec4d7496c44 \ - --hash=sha256:398dc3dc9e7079290548be96102b5bb9179c922534ef166bf22478b6b477b42c \ - --hash=sha256:401593f23e85d5531754ca0fb5bb4e251959dcd1b2864e5a28844004ab1a7231 \ - --hash=sha256:4252bee4ec51effe858aa3ac17ca09520a7dedfe4456a23dd286332e501ea7b9 \ - --hash=sha256:4297dd4d13869f14192ae257527cb8d499273509e6bc166ac92eb0a8ec25f1fe \ - --hash=sha256:447ff21a0eb76dfa78a6164e752a1c1205c055f22145178048cd619dada4e72f \ - --hash=sha256:482ee5caad2244472d7572c555a777e459207770483775d6a694c3ef2f9e5e45 \ - --hash=sha256:4bd24eedddbdd7980e698ab0f588e2e9d641c434f586970a57164259f9ce2db4 \ - --hash=sha256:6062b07b25c766cb8c7a94a64755093a7bc7e7aa0ff39f0f44d13a47d5696619 \ - --hash=sha256:68121213c675ebf23c4d1e0c7f3e60f2db7648e2d7da6323efd62a684b2a64b6 \ - --hash=sha256:7b7e17ff038795f96b64a1e0261338aba2d36857324bd582fedbe05d41542a81 \ - --hash=sha256:8064c7896361a5451371c2d4b03660ba85f673ce00e4c57fed5e355f268dca9b \ - --hash=sha256:83c54241552e35174ad44e90915aebd251beee31f9176a16ec931e8ce65c882d \ - --hash=sha256:863a67bbd0899deefdb1cc7c5b7c03a3f98aae237b0f5fb6311beed2901102e2 \ - --hash=sha256:875f8755842a38db7cda27dfa7f92fe4ef004aaaa49d8b23721193c2010076ef \ - --hash=sha256:951b6a7e49dacef27181f6d1b15db368d9584e0a802dd61cd9fab949ce339ee8 \ - --hash=sha256:aad7ca6f38e7e82bc28ed8473a4649d24249f438543ed6879776d8ef5dc2e743 \ - --hash=sha256:b043748caaeb82655982479b39189f76c1948903230e7cd33057efc66737003f \ - --hash=sha256:ba0404ddf8f95206328993f3db1b50f06d3034bc84c4440c4df4ce86060cee73 \ - --hash=sha256:bcc4142e0465dcfecbec6908896aa4b43ae8d4ca0b3fa88a23fe6d4ee5033b96 \ - --hash=sha256:c7ab3edbac04723bbc3d8c849d824f7bab63c969c14dc0f876d894d06787919a \ - --hash=sha256:f5543ff7c6c64afbded02e9d99b5f142efc12ed5cefefa070a6914b3641d7b02 \ - --hash=sha256:f56d680c2129dcbb5d96439921a1f14a2a072db904fa96ed2c52bef6daa8559c \ - --hash=sha256:fbe467dc7800e257306d43761b61aeaaead8b8ac8ab35d0b296cf4ec9e1d71de \ - --hash=sha256:ffae157ecde933f4dca4c13775ad3c0e7fc846c6b538965bd9222d4bf7ccfa9a +apache-beam[dataframe,gcp,test,yaml]==2.62.0 \ + --hash=sha256:02d33aae5a4cc3acc7a2fb86e3632cdbd240522256778e1da0f6b9192eeef91e \ + --hash=sha256:04c58ef6827142b39a4c95f3403e388646fde8d88e823c7d4f624b45dea459fa \ + --hash=sha256:04e99ef0fd74b645971549a16576f41a7a3c7a5360b67723a906334d70d04be3 \ + --hash=sha256:147491dfde40c9ac0353899fc6632d92d24663c8f9d44ea30157e66752b6f54c \ + --hash=sha256:158bce813662a39e2ee504273cc5fc492779703b8f596ef1a3210a62a5263b10 \ + --hash=sha256:1e8f741de5c66122f5c97f8a6838ab7bfdbe7bbbbdadeef9f91bd0561487c26d \ + --hash=sha256:3489d45fb04d542061af8f59b908e7a0168da5aacded308bb7825fd43f7068c7 \ + --hash=sha256:34d353f5a9aeda4a3ee484907b14e2942b9e8f7f8a112b5a98d69663ed4ef68a \ + --hash=sha256:3d5112494e4e672af404a8cb13dce3c12e3e11e5aaae7d78bc1b2c640f1e8c05 \ + --hash=sha256:5044f2e2608d8e52b8267ec0fba250814388dd97c3ca7107d7cad0897895cbb8 \ + --hash=sha256:5e5584dd4d68e1f1ace4c1775707afb5309852332ecc4975344bcc8a300d7399 \ + --hash=sha256:8843a8306c0548c0224e7f0567de9494552068bd76101b6cc4bef445c3ffa495 \ + --hash=sha256:8b79b8dc2968321d433d8d353a5b4c86c63e3a16cd9aced62c73e8ce3269d3cb \ + --hash=sha256:b158b0c0d8a18e0f0b5c32031b61c51e19b12825312d8c01533c61d65b5fbda4 \ + --hash=sha256:b61f298a43b7672604a4d3c4f3eef413f6c9b55aeadcacd06631d6ccc319aee8 \ + --hash=sha256:b771ad9202816ddd1d887cbe1083b9711b8b3593c0a78f2e85a1d7f5c0adbdac \ + --hash=sha256:b9d97df88b9b9e4585fff5ee09959d76b0ab596bb78ae986fac8c04bf8cc78db \ + --hash=sha256:bc5dd62c005526c82d6ed1ffde7324e5347c1ff417061b5e63c330dc02e9e601 \ + --hash=sha256:c4d5a43bb601520ce5ba30505a1597d2f4f0a02fbf56ca78213565b4c0ae7420 \ + --hash=sha256:c7c1632a29ed785a93e5f9c8bed3e18d962789d06c8acc943f6faf9e24a177b7 \ + --hash=sha256:c947f13bf6b8f7904994a3d846fe71ea2b28991373316c205987a42da8df4084 \ + --hash=sha256:e24db3b37969353f0fdf8c13f2127a391d4483dcb81b2cf6211d37108bd8599a \ + --hash=sha256:e65d11b8ac8eb84cbff56fe2aefb6da6449aee07339755138c8bce3d4d7df206 \ + --hash=sha256:f28d8a79552fceeaaf0ed0b0f2b41b2143e1013745a5847d7defbb4a6ebfe9a1 \ + --hash=sha256:f30e40163a23a64a4469ca2c74674eff7b1b5fcfd49c1461565c4aeda978a096 # via -r python/default_base_yaml_requirements.txt attrs==24.2.0 \ --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ @@ -1072,74 +1066,79 @@ protobuf==4.25.5 \ # grpc-google-iam-v1 # grpcio-status # proto-plus -psycopg2-binary==2.9.10 \ - --hash=sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff \ - --hash=sha256:056470c3dc57904bbf63d6f534988bafc4e970ffd50f6271fc4ee7daad9498a5 \ - --hash=sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f \ - --hash=sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5 \ - --hash=sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0 \ - --hash=sha256:19721ac03892001ee8fdd11507e6a2e01f4e37014def96379411ca99d78aeb2c \ - --hash=sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c \ - --hash=sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341 \ - --hash=sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f \ - --hash=sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7 \ - --hash=sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d \ - --hash=sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007 \ - --hash=sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92 \ - --hash=sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb \ - --hash=sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5 \ - --hash=sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5 \ - --hash=sha256:3216ccf953b3f267691c90c6fe742e45d890d8272326b4a8b20850a03d05b7b8 \ - --hash=sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1 \ - --hash=sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68 \ - --hash=sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73 \ - --hash=sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1 \ - --hash=sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53 \ - --hash=sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d \ - --hash=sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906 \ - --hash=sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0 \ - --hash=sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2 \ - --hash=sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a \ - --hash=sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b \ - --hash=sha256:5c370b1e4975df846b0277b4deba86419ca77dbc25047f535b0bb03d1a544d44 \ - --hash=sha256:6b269105e59ac96aba877c1707c600ae55711d9dcd3fc4b5012e4af68e30c648 \ - --hash=sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7 \ - --hash=sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f \ - --hash=sha256:73aa0e31fa4bb82578f3a6c74a73c273367727de397a7a0f07bd83cbea696baa \ - --hash=sha256:7559bce4b505762d737172556a4e6ea8a9998ecac1e39b5233465093e8cee697 \ - --hash=sha256:79625966e176dc97ddabc142351e0409e28acf4660b88d1cf6adb876d20c490d \ - --hash=sha256:7a813c8bdbaaaab1f078014b9b0b13f5de757e2b5d9be6403639b298a04d218b \ - --hash=sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526 \ - --hash=sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4 \ - --hash=sha256:7f5d859928e635fa3ce3477704acee0f667b3a3d3e4bb109f2b18d4005f38287 \ - --hash=sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e \ - --hash=sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673 \ - --hash=sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0 \ - --hash=sha256:8aabf1c1a04584c168984ac678a668094d831f152859d06e055288fa515e4d30 \ - --hash=sha256:8aecc5e80c63f7459a1a2ab2c64df952051df196294d9f739933a9f6687e86b3 \ - --hash=sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e \ - --hash=sha256:8de718c0e1c4b982a54b41779667242bc630b2197948405b7bd8ce16bcecac92 \ - --hash=sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a \ - --hash=sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c \ - --hash=sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8 \ - --hash=sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909 \ - --hash=sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47 \ - --hash=sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864 \ - --hash=sha256:d00924255d7fc916ef66e4bf22f354a940c67179ad3fd7067d7a0a9c84d2fbfc \ - --hash=sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00 \ - --hash=sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb \ - --hash=sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539 \ - --hash=sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b \ - --hash=sha256:e8b58f0a96e7a1e341fc894f62c1177a7c83febebb5ff9123b579418fdc8a481 \ - --hash=sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5 \ - --hash=sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4 \ - --hash=sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64 \ - --hash=sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392 \ - --hash=sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4 \ - --hash=sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1 \ - --hash=sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1 \ - --hash=sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567 \ - --hash=sha256:ffe8ed017e4ed70f68b7b371d84b7d4a790368db9203dfc2d222febd3a9c8863 +psycopg2-binary==2.9.9 \ + --hash=sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9 \ + --hash=sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77 \ + --hash=sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e \ + --hash=sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84 \ + --hash=sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3 \ + --hash=sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2 \ + --hash=sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67 \ + --hash=sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876 \ + --hash=sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152 \ + --hash=sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f \ + --hash=sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a \ + --hash=sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6 \ + --hash=sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503 \ + --hash=sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f \ + --hash=sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493 \ + --hash=sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996 \ + --hash=sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f \ + --hash=sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e \ + --hash=sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59 \ + --hash=sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94 \ + --hash=sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7 \ + --hash=sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682 \ + --hash=sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420 \ + --hash=sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae \ + --hash=sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291 \ + --hash=sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe \ + --hash=sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980 \ + --hash=sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93 \ + --hash=sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692 \ + --hash=sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119 \ + --hash=sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716 \ + --hash=sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472 \ + --hash=sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b \ + --hash=sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2 \ + --hash=sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc \ + --hash=sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c \ + --hash=sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5 \ + --hash=sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab \ + --hash=sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984 \ + --hash=sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9 \ + --hash=sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf \ + --hash=sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0 \ + --hash=sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f \ + --hash=sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212 \ + --hash=sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb \ + --hash=sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be \ + --hash=sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90 \ + --hash=sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041 \ + --hash=sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7 \ + --hash=sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860 \ + --hash=sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d \ + --hash=sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245 \ + --hash=sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27 \ + --hash=sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417 \ + --hash=sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359 \ + --hash=sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202 \ + --hash=sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0 \ + --hash=sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7 \ + --hash=sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba \ + --hash=sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1 \ + --hash=sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd \ + --hash=sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07 \ + --hash=sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98 \ + --hash=sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55 \ + --hash=sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d \ + --hash=sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972 \ + --hash=sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f \ + --hash=sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e \ + --hash=sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26 \ + --hash=sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957 \ + --hash=sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53 \ + --hash=sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52 # via apache-beam pyarrow==16.1.0 \ --hash=sha256:06ebccb6f8cb7357de85f60d5da50e83507954af617d7b05f48af1621d331c9a \ @@ -1820,7 +1819,9 @@ six==1.16.0 \ sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 - # via hypothesis + # via + # apache-beam + # hypothesis sqlalchemy==2.0.36 \ --hash=sha256:03e08af7a5f9386a43919eda9de33ffda16b44eb11f3b313e6822243770e9763 \ --hash=sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436 \ diff --git a/v2/googlecloud-to-googlecloud/src/main/resources/requirements.txt b/v2/googlecloud-to-googlecloud/src/main/resources/requirements.txt index 4095f3e5bc..ec9e39172c 100644 --- a/v2/googlecloud-to-googlecloud/src/main/resources/requirements.txt +++ b/v2/googlecloud-to-googlecloud/src/main/resources/requirements.txt @@ -27,38 +27,32 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -apache-beam[dataframe,gcp,test,yaml]==2.60.0 \ - --hash=sha256:04644d4021522674b56c32b199c8ca89ee9ffef6eee1b21a29a6b8cd0fdfc16c \ - --hash=sha256:0594dff34776f4929aa24b35b677d5b2688c6e565e6a32921fad7d7c6a4063a0 \ - --hash=sha256:10e4ecd11e7b3c9149e3704b6fc3a5f98ae63c889167681e4e18d9633d34957c \ - --hash=sha256:12f292ee820e37ba0bf47ed54173cb6d15cce24beaa28a676e85ddb3f0a55263 \ - --hash=sha256:239b02a82d8abd0400e8f2316b2b4ee08092c898d3eac36ffa7e3a632612fbb4 \ - --hash=sha256:354f8c058b15608d1a79da55edc4f8fa724fff92269db02a81ccb3dfa82e08a5 \ - --hash=sha256:3728ee7c0e9efcd9e1323ccf5dbebf5d56f7ce0fcc5ec78e63747ec4d7496c44 \ - --hash=sha256:398dc3dc9e7079290548be96102b5bb9179c922534ef166bf22478b6b477b42c \ - --hash=sha256:401593f23e85d5531754ca0fb5bb4e251959dcd1b2864e5a28844004ab1a7231 \ - --hash=sha256:4252bee4ec51effe858aa3ac17ca09520a7dedfe4456a23dd286332e501ea7b9 \ - --hash=sha256:4297dd4d13869f14192ae257527cb8d499273509e6bc166ac92eb0a8ec25f1fe \ - --hash=sha256:447ff21a0eb76dfa78a6164e752a1c1205c055f22145178048cd619dada4e72f \ - --hash=sha256:482ee5caad2244472d7572c555a777e459207770483775d6a694c3ef2f9e5e45 \ - --hash=sha256:4bd24eedddbdd7980e698ab0f588e2e9d641c434f586970a57164259f9ce2db4 \ - --hash=sha256:6062b07b25c766cb8c7a94a64755093a7bc7e7aa0ff39f0f44d13a47d5696619 \ - --hash=sha256:68121213c675ebf23c4d1e0c7f3e60f2db7648e2d7da6323efd62a684b2a64b6 \ - --hash=sha256:7b7e17ff038795f96b64a1e0261338aba2d36857324bd582fedbe05d41542a81 \ - --hash=sha256:8064c7896361a5451371c2d4b03660ba85f673ce00e4c57fed5e355f268dca9b \ - --hash=sha256:83c54241552e35174ad44e90915aebd251beee31f9176a16ec931e8ce65c882d \ - --hash=sha256:863a67bbd0899deefdb1cc7c5b7c03a3f98aae237b0f5fb6311beed2901102e2 \ - --hash=sha256:875f8755842a38db7cda27dfa7f92fe4ef004aaaa49d8b23721193c2010076ef \ - --hash=sha256:951b6a7e49dacef27181f6d1b15db368d9584e0a802dd61cd9fab949ce339ee8 \ - --hash=sha256:aad7ca6f38e7e82bc28ed8473a4649d24249f438543ed6879776d8ef5dc2e743 \ - --hash=sha256:b043748caaeb82655982479b39189f76c1948903230e7cd33057efc66737003f \ - --hash=sha256:ba0404ddf8f95206328993f3db1b50f06d3034bc84c4440c4df4ce86060cee73 \ - --hash=sha256:bcc4142e0465dcfecbec6908896aa4b43ae8d4ca0b3fa88a23fe6d4ee5033b96 \ - --hash=sha256:c7ab3edbac04723bbc3d8c849d824f7bab63c969c14dc0f876d894d06787919a \ - --hash=sha256:f5543ff7c6c64afbded02e9d99b5f142efc12ed5cefefa070a6914b3641d7b02 \ - --hash=sha256:f56d680c2129dcbb5d96439921a1f14a2a072db904fa96ed2c52bef6daa8559c \ - --hash=sha256:fbe467dc7800e257306d43761b61aeaaead8b8ac8ab35d0b296cf4ec9e1d71de \ - --hash=sha256:ffae157ecde933f4dca4c13775ad3c0e7fc846c6b538965bd9222d4bf7ccfa9a +apache-beam[dataframe,gcp,test,yaml]==2.62.0 \ + --hash=sha256:02d33aae5a4cc3acc7a2fb86e3632cdbd240522256778e1da0f6b9192eeef91e \ + --hash=sha256:04c58ef6827142b39a4c95f3403e388646fde8d88e823c7d4f624b45dea459fa \ + --hash=sha256:04e99ef0fd74b645971549a16576f41a7a3c7a5360b67723a906334d70d04be3 \ + --hash=sha256:147491dfde40c9ac0353899fc6632d92d24663c8f9d44ea30157e66752b6f54c \ + --hash=sha256:158bce813662a39e2ee504273cc5fc492779703b8f596ef1a3210a62a5263b10 \ + --hash=sha256:1e8f741de5c66122f5c97f8a6838ab7bfdbe7bbbbdadeef9f91bd0561487c26d \ + --hash=sha256:3489d45fb04d542061af8f59b908e7a0168da5aacded308bb7825fd43f7068c7 \ + --hash=sha256:34d353f5a9aeda4a3ee484907b14e2942b9e8f7f8a112b5a98d69663ed4ef68a \ + --hash=sha256:3d5112494e4e672af404a8cb13dce3c12e3e11e5aaae7d78bc1b2c640f1e8c05 \ + --hash=sha256:5044f2e2608d8e52b8267ec0fba250814388dd97c3ca7107d7cad0897895cbb8 \ + --hash=sha256:5e5584dd4d68e1f1ace4c1775707afb5309852332ecc4975344bcc8a300d7399 \ + --hash=sha256:8843a8306c0548c0224e7f0567de9494552068bd76101b6cc4bef445c3ffa495 \ + --hash=sha256:8b79b8dc2968321d433d8d353a5b4c86c63e3a16cd9aced62c73e8ce3269d3cb \ + --hash=sha256:b158b0c0d8a18e0f0b5c32031b61c51e19b12825312d8c01533c61d65b5fbda4 \ + --hash=sha256:b61f298a43b7672604a4d3c4f3eef413f6c9b55aeadcacd06631d6ccc319aee8 \ + --hash=sha256:b771ad9202816ddd1d887cbe1083b9711b8b3593c0a78f2e85a1d7f5c0adbdac \ + --hash=sha256:b9d97df88b9b9e4585fff5ee09959d76b0ab596bb78ae986fac8c04bf8cc78db \ + --hash=sha256:bc5dd62c005526c82d6ed1ffde7324e5347c1ff417061b5e63c330dc02e9e601 \ + --hash=sha256:c4d5a43bb601520ce5ba30505a1597d2f4f0a02fbf56ca78213565b4c0ae7420 \ + --hash=sha256:c7c1632a29ed785a93e5f9c8bed3e18d962789d06c8acc943f6faf9e24a177b7 \ + --hash=sha256:c947f13bf6b8f7904994a3d846fe71ea2b28991373316c205987a42da8df4084 \ + --hash=sha256:e24db3b37969353f0fdf8c13f2127a391d4483dcb81b2cf6211d37108bd8599a \ + --hash=sha256:e65d11b8ac8eb84cbff56fe2aefb6da6449aee07339755138c8bce3d4d7df206 \ + --hash=sha256:f28d8a79552fceeaaf0ed0b0f2b41b2143e1013745a5847d7defbb4a6ebfe9a1 \ + --hash=sha256:f30e40163a23a64a4469ca2c74674eff7b1b5fcfd49c1461565c4aeda978a096 # via -r python/default_base_yaml_requirements.txt attrs==24.2.0 \ --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ @@ -1072,74 +1066,79 @@ protobuf==4.25.5 \ # grpc-google-iam-v1 # grpcio-status # proto-plus -psycopg2-binary==2.9.10 \ - --hash=sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff \ - --hash=sha256:056470c3dc57904bbf63d6f534988bafc4e970ffd50f6271fc4ee7daad9498a5 \ - --hash=sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f \ - --hash=sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5 \ - --hash=sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0 \ - --hash=sha256:19721ac03892001ee8fdd11507e6a2e01f4e37014def96379411ca99d78aeb2c \ - --hash=sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c \ - --hash=sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341 \ - --hash=sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f \ - --hash=sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7 \ - --hash=sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d \ - --hash=sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007 \ - --hash=sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92 \ - --hash=sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb \ - --hash=sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5 \ - --hash=sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5 \ - --hash=sha256:3216ccf953b3f267691c90c6fe742e45d890d8272326b4a8b20850a03d05b7b8 \ - --hash=sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1 \ - --hash=sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68 \ - --hash=sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73 \ - --hash=sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1 \ - --hash=sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53 \ - --hash=sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d \ - --hash=sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906 \ - --hash=sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0 \ - --hash=sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2 \ - --hash=sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a \ - --hash=sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b \ - --hash=sha256:5c370b1e4975df846b0277b4deba86419ca77dbc25047f535b0bb03d1a544d44 \ - --hash=sha256:6b269105e59ac96aba877c1707c600ae55711d9dcd3fc4b5012e4af68e30c648 \ - --hash=sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7 \ - --hash=sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f \ - --hash=sha256:73aa0e31fa4bb82578f3a6c74a73c273367727de397a7a0f07bd83cbea696baa \ - --hash=sha256:7559bce4b505762d737172556a4e6ea8a9998ecac1e39b5233465093e8cee697 \ - --hash=sha256:79625966e176dc97ddabc142351e0409e28acf4660b88d1cf6adb876d20c490d \ - --hash=sha256:7a813c8bdbaaaab1f078014b9b0b13f5de757e2b5d9be6403639b298a04d218b \ - --hash=sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526 \ - --hash=sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4 \ - --hash=sha256:7f5d859928e635fa3ce3477704acee0f667b3a3d3e4bb109f2b18d4005f38287 \ - --hash=sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e \ - --hash=sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673 \ - --hash=sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0 \ - --hash=sha256:8aabf1c1a04584c168984ac678a668094d831f152859d06e055288fa515e4d30 \ - --hash=sha256:8aecc5e80c63f7459a1a2ab2c64df952051df196294d9f739933a9f6687e86b3 \ - --hash=sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e \ - --hash=sha256:8de718c0e1c4b982a54b41779667242bc630b2197948405b7bd8ce16bcecac92 \ - --hash=sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a \ - --hash=sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c \ - --hash=sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8 \ - --hash=sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909 \ - --hash=sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47 \ - --hash=sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864 \ - --hash=sha256:d00924255d7fc916ef66e4bf22f354a940c67179ad3fd7067d7a0a9c84d2fbfc \ - --hash=sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00 \ - --hash=sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb \ - --hash=sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539 \ - --hash=sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b \ - --hash=sha256:e8b58f0a96e7a1e341fc894f62c1177a7c83febebb5ff9123b579418fdc8a481 \ - --hash=sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5 \ - --hash=sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4 \ - --hash=sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64 \ - --hash=sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392 \ - --hash=sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4 \ - --hash=sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1 \ - --hash=sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1 \ - --hash=sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567 \ - --hash=sha256:ffe8ed017e4ed70f68b7b371d84b7d4a790368db9203dfc2d222febd3a9c8863 +psycopg2-binary==2.9.9 \ + --hash=sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9 \ + --hash=sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77 \ + --hash=sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e \ + --hash=sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84 \ + --hash=sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3 \ + --hash=sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2 \ + --hash=sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67 \ + --hash=sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876 \ + --hash=sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152 \ + --hash=sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f \ + --hash=sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a \ + --hash=sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6 \ + --hash=sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503 \ + --hash=sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f \ + --hash=sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493 \ + --hash=sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996 \ + --hash=sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f \ + --hash=sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e \ + --hash=sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59 \ + --hash=sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94 \ + --hash=sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7 \ + --hash=sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682 \ + --hash=sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420 \ + --hash=sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae \ + --hash=sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291 \ + --hash=sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe \ + --hash=sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980 \ + --hash=sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93 \ + --hash=sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692 \ + --hash=sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119 \ + --hash=sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716 \ + --hash=sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472 \ + --hash=sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b \ + --hash=sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2 \ + --hash=sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc \ + --hash=sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c \ + --hash=sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5 \ + --hash=sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab \ + --hash=sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984 \ + --hash=sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9 \ + --hash=sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf \ + --hash=sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0 \ + --hash=sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f \ + --hash=sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212 \ + --hash=sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb \ + --hash=sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be \ + --hash=sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90 \ + --hash=sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041 \ + --hash=sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7 \ + --hash=sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860 \ + --hash=sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d \ + --hash=sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245 \ + --hash=sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27 \ + --hash=sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417 \ + --hash=sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359 \ + --hash=sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202 \ + --hash=sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0 \ + --hash=sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7 \ + --hash=sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba \ + --hash=sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1 \ + --hash=sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd \ + --hash=sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07 \ + --hash=sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98 \ + --hash=sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55 \ + --hash=sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d \ + --hash=sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972 \ + --hash=sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f \ + --hash=sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e \ + --hash=sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26 \ + --hash=sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957 \ + --hash=sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53 \ + --hash=sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52 # via apache-beam pyarrow==16.1.0 \ --hash=sha256:06ebccb6f8cb7357de85f60d5da50e83507954af617d7b05f48af1621d331c9a \ @@ -1820,7 +1819,9 @@ six==1.16.0 \ sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 - # via hypothesis + # via + # apache-beam + # hypothesis sqlalchemy==2.0.36 \ --hash=sha256:03e08af7a5f9386a43919eda9de33ffda16b44eb11f3b313e6822243770e9763 \ --hash=sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436 \ diff --git a/v2/googlecloud-to-splunk/src/main/resources/requirements.txt b/v2/googlecloud-to-splunk/src/main/resources/requirements.txt index 4095f3e5bc..ec9e39172c 100644 --- a/v2/googlecloud-to-splunk/src/main/resources/requirements.txt +++ b/v2/googlecloud-to-splunk/src/main/resources/requirements.txt @@ -27,38 +27,32 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -apache-beam[dataframe,gcp,test,yaml]==2.60.0 \ - --hash=sha256:04644d4021522674b56c32b199c8ca89ee9ffef6eee1b21a29a6b8cd0fdfc16c \ - --hash=sha256:0594dff34776f4929aa24b35b677d5b2688c6e565e6a32921fad7d7c6a4063a0 \ - --hash=sha256:10e4ecd11e7b3c9149e3704b6fc3a5f98ae63c889167681e4e18d9633d34957c \ - --hash=sha256:12f292ee820e37ba0bf47ed54173cb6d15cce24beaa28a676e85ddb3f0a55263 \ - --hash=sha256:239b02a82d8abd0400e8f2316b2b4ee08092c898d3eac36ffa7e3a632612fbb4 \ - --hash=sha256:354f8c058b15608d1a79da55edc4f8fa724fff92269db02a81ccb3dfa82e08a5 \ - --hash=sha256:3728ee7c0e9efcd9e1323ccf5dbebf5d56f7ce0fcc5ec78e63747ec4d7496c44 \ - --hash=sha256:398dc3dc9e7079290548be96102b5bb9179c922534ef166bf22478b6b477b42c \ - --hash=sha256:401593f23e85d5531754ca0fb5bb4e251959dcd1b2864e5a28844004ab1a7231 \ - --hash=sha256:4252bee4ec51effe858aa3ac17ca09520a7dedfe4456a23dd286332e501ea7b9 \ - --hash=sha256:4297dd4d13869f14192ae257527cb8d499273509e6bc166ac92eb0a8ec25f1fe \ - --hash=sha256:447ff21a0eb76dfa78a6164e752a1c1205c055f22145178048cd619dada4e72f \ - --hash=sha256:482ee5caad2244472d7572c555a777e459207770483775d6a694c3ef2f9e5e45 \ - --hash=sha256:4bd24eedddbdd7980e698ab0f588e2e9d641c434f586970a57164259f9ce2db4 \ - --hash=sha256:6062b07b25c766cb8c7a94a64755093a7bc7e7aa0ff39f0f44d13a47d5696619 \ - --hash=sha256:68121213c675ebf23c4d1e0c7f3e60f2db7648e2d7da6323efd62a684b2a64b6 \ - --hash=sha256:7b7e17ff038795f96b64a1e0261338aba2d36857324bd582fedbe05d41542a81 \ - --hash=sha256:8064c7896361a5451371c2d4b03660ba85f673ce00e4c57fed5e355f268dca9b \ - --hash=sha256:83c54241552e35174ad44e90915aebd251beee31f9176a16ec931e8ce65c882d \ - --hash=sha256:863a67bbd0899deefdb1cc7c5b7c03a3f98aae237b0f5fb6311beed2901102e2 \ - --hash=sha256:875f8755842a38db7cda27dfa7f92fe4ef004aaaa49d8b23721193c2010076ef \ - --hash=sha256:951b6a7e49dacef27181f6d1b15db368d9584e0a802dd61cd9fab949ce339ee8 \ - --hash=sha256:aad7ca6f38e7e82bc28ed8473a4649d24249f438543ed6879776d8ef5dc2e743 \ - --hash=sha256:b043748caaeb82655982479b39189f76c1948903230e7cd33057efc66737003f \ - --hash=sha256:ba0404ddf8f95206328993f3db1b50f06d3034bc84c4440c4df4ce86060cee73 \ - --hash=sha256:bcc4142e0465dcfecbec6908896aa4b43ae8d4ca0b3fa88a23fe6d4ee5033b96 \ - --hash=sha256:c7ab3edbac04723bbc3d8c849d824f7bab63c969c14dc0f876d894d06787919a \ - --hash=sha256:f5543ff7c6c64afbded02e9d99b5f142efc12ed5cefefa070a6914b3641d7b02 \ - --hash=sha256:f56d680c2129dcbb5d96439921a1f14a2a072db904fa96ed2c52bef6daa8559c \ - --hash=sha256:fbe467dc7800e257306d43761b61aeaaead8b8ac8ab35d0b296cf4ec9e1d71de \ - --hash=sha256:ffae157ecde933f4dca4c13775ad3c0e7fc846c6b538965bd9222d4bf7ccfa9a +apache-beam[dataframe,gcp,test,yaml]==2.62.0 \ + --hash=sha256:02d33aae5a4cc3acc7a2fb86e3632cdbd240522256778e1da0f6b9192eeef91e \ + --hash=sha256:04c58ef6827142b39a4c95f3403e388646fde8d88e823c7d4f624b45dea459fa \ + --hash=sha256:04e99ef0fd74b645971549a16576f41a7a3c7a5360b67723a906334d70d04be3 \ + --hash=sha256:147491dfde40c9ac0353899fc6632d92d24663c8f9d44ea30157e66752b6f54c \ + --hash=sha256:158bce813662a39e2ee504273cc5fc492779703b8f596ef1a3210a62a5263b10 \ + --hash=sha256:1e8f741de5c66122f5c97f8a6838ab7bfdbe7bbbbdadeef9f91bd0561487c26d \ + --hash=sha256:3489d45fb04d542061af8f59b908e7a0168da5aacded308bb7825fd43f7068c7 \ + --hash=sha256:34d353f5a9aeda4a3ee484907b14e2942b9e8f7f8a112b5a98d69663ed4ef68a \ + --hash=sha256:3d5112494e4e672af404a8cb13dce3c12e3e11e5aaae7d78bc1b2c640f1e8c05 \ + --hash=sha256:5044f2e2608d8e52b8267ec0fba250814388dd97c3ca7107d7cad0897895cbb8 \ + --hash=sha256:5e5584dd4d68e1f1ace4c1775707afb5309852332ecc4975344bcc8a300d7399 \ + --hash=sha256:8843a8306c0548c0224e7f0567de9494552068bd76101b6cc4bef445c3ffa495 \ + --hash=sha256:8b79b8dc2968321d433d8d353a5b4c86c63e3a16cd9aced62c73e8ce3269d3cb \ + --hash=sha256:b158b0c0d8a18e0f0b5c32031b61c51e19b12825312d8c01533c61d65b5fbda4 \ + --hash=sha256:b61f298a43b7672604a4d3c4f3eef413f6c9b55aeadcacd06631d6ccc319aee8 \ + --hash=sha256:b771ad9202816ddd1d887cbe1083b9711b8b3593c0a78f2e85a1d7f5c0adbdac \ + --hash=sha256:b9d97df88b9b9e4585fff5ee09959d76b0ab596bb78ae986fac8c04bf8cc78db \ + --hash=sha256:bc5dd62c005526c82d6ed1ffde7324e5347c1ff417061b5e63c330dc02e9e601 \ + --hash=sha256:c4d5a43bb601520ce5ba30505a1597d2f4f0a02fbf56ca78213565b4c0ae7420 \ + --hash=sha256:c7c1632a29ed785a93e5f9c8bed3e18d962789d06c8acc943f6faf9e24a177b7 \ + --hash=sha256:c947f13bf6b8f7904994a3d846fe71ea2b28991373316c205987a42da8df4084 \ + --hash=sha256:e24db3b37969353f0fdf8c13f2127a391d4483dcb81b2cf6211d37108bd8599a \ + --hash=sha256:e65d11b8ac8eb84cbff56fe2aefb6da6449aee07339755138c8bce3d4d7df206 \ + --hash=sha256:f28d8a79552fceeaaf0ed0b0f2b41b2143e1013745a5847d7defbb4a6ebfe9a1 \ + --hash=sha256:f30e40163a23a64a4469ca2c74674eff7b1b5fcfd49c1461565c4aeda978a096 # via -r python/default_base_yaml_requirements.txt attrs==24.2.0 \ --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ @@ -1072,74 +1066,79 @@ protobuf==4.25.5 \ # grpc-google-iam-v1 # grpcio-status # proto-plus -psycopg2-binary==2.9.10 \ - --hash=sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff \ - --hash=sha256:056470c3dc57904bbf63d6f534988bafc4e970ffd50f6271fc4ee7daad9498a5 \ - --hash=sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f \ - --hash=sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5 \ - --hash=sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0 \ - --hash=sha256:19721ac03892001ee8fdd11507e6a2e01f4e37014def96379411ca99d78aeb2c \ - --hash=sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c \ - --hash=sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341 \ - --hash=sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f \ - --hash=sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7 \ - --hash=sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d \ - --hash=sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007 \ - --hash=sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92 \ - --hash=sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb \ - --hash=sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5 \ - --hash=sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5 \ - --hash=sha256:3216ccf953b3f267691c90c6fe742e45d890d8272326b4a8b20850a03d05b7b8 \ - --hash=sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1 \ - --hash=sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68 \ - --hash=sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73 \ - --hash=sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1 \ - --hash=sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53 \ - --hash=sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d \ - --hash=sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906 \ - --hash=sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0 \ - --hash=sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2 \ - --hash=sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a \ - --hash=sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b \ - --hash=sha256:5c370b1e4975df846b0277b4deba86419ca77dbc25047f535b0bb03d1a544d44 \ - --hash=sha256:6b269105e59ac96aba877c1707c600ae55711d9dcd3fc4b5012e4af68e30c648 \ - --hash=sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7 \ - --hash=sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f \ - --hash=sha256:73aa0e31fa4bb82578f3a6c74a73c273367727de397a7a0f07bd83cbea696baa \ - --hash=sha256:7559bce4b505762d737172556a4e6ea8a9998ecac1e39b5233465093e8cee697 \ - --hash=sha256:79625966e176dc97ddabc142351e0409e28acf4660b88d1cf6adb876d20c490d \ - --hash=sha256:7a813c8bdbaaaab1f078014b9b0b13f5de757e2b5d9be6403639b298a04d218b \ - --hash=sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526 \ - --hash=sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4 \ - --hash=sha256:7f5d859928e635fa3ce3477704acee0f667b3a3d3e4bb109f2b18d4005f38287 \ - --hash=sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e \ - --hash=sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673 \ - --hash=sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0 \ - --hash=sha256:8aabf1c1a04584c168984ac678a668094d831f152859d06e055288fa515e4d30 \ - --hash=sha256:8aecc5e80c63f7459a1a2ab2c64df952051df196294d9f739933a9f6687e86b3 \ - --hash=sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e \ - --hash=sha256:8de718c0e1c4b982a54b41779667242bc630b2197948405b7bd8ce16bcecac92 \ - --hash=sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a \ - --hash=sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c \ - --hash=sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8 \ - --hash=sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909 \ - --hash=sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47 \ - --hash=sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864 \ - --hash=sha256:d00924255d7fc916ef66e4bf22f354a940c67179ad3fd7067d7a0a9c84d2fbfc \ - --hash=sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00 \ - --hash=sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb \ - --hash=sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539 \ - --hash=sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b \ - --hash=sha256:e8b58f0a96e7a1e341fc894f62c1177a7c83febebb5ff9123b579418fdc8a481 \ - --hash=sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5 \ - --hash=sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4 \ - --hash=sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64 \ - --hash=sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392 \ - --hash=sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4 \ - --hash=sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1 \ - --hash=sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1 \ - --hash=sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567 \ - --hash=sha256:ffe8ed017e4ed70f68b7b371d84b7d4a790368db9203dfc2d222febd3a9c8863 +psycopg2-binary==2.9.9 \ + --hash=sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9 \ + --hash=sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77 \ + --hash=sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e \ + --hash=sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84 \ + --hash=sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3 \ + --hash=sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2 \ + --hash=sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67 \ + --hash=sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876 \ + --hash=sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152 \ + --hash=sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f \ + --hash=sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a \ + --hash=sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6 \ + --hash=sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503 \ + --hash=sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f \ + --hash=sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493 \ + --hash=sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996 \ + --hash=sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f \ + --hash=sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e \ + --hash=sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59 \ + --hash=sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94 \ + --hash=sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7 \ + --hash=sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682 \ + --hash=sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420 \ + --hash=sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae \ + --hash=sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291 \ + --hash=sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe \ + --hash=sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980 \ + --hash=sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93 \ + --hash=sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692 \ + --hash=sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119 \ + --hash=sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716 \ + --hash=sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472 \ + --hash=sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b \ + --hash=sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2 \ + --hash=sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc \ + --hash=sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c \ + --hash=sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5 \ + --hash=sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab \ + --hash=sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984 \ + --hash=sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9 \ + --hash=sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf \ + --hash=sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0 \ + --hash=sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f \ + --hash=sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212 \ + --hash=sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb \ + --hash=sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be \ + --hash=sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90 \ + --hash=sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041 \ + --hash=sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7 \ + --hash=sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860 \ + --hash=sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d \ + --hash=sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245 \ + --hash=sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27 \ + --hash=sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417 \ + --hash=sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359 \ + --hash=sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202 \ + --hash=sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0 \ + --hash=sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7 \ + --hash=sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba \ + --hash=sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1 \ + --hash=sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd \ + --hash=sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07 \ + --hash=sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98 \ + --hash=sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55 \ + --hash=sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d \ + --hash=sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972 \ + --hash=sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f \ + --hash=sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e \ + --hash=sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26 \ + --hash=sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957 \ + --hash=sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53 \ + --hash=sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52 # via apache-beam pyarrow==16.1.0 \ --hash=sha256:06ebccb6f8cb7357de85f60d5da50e83507954af617d7b05f48af1621d331c9a \ @@ -1820,7 +1819,9 @@ six==1.16.0 \ sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 - # via hypothesis + # via + # apache-beam + # hypothesis sqlalchemy==2.0.36 \ --hash=sha256:03e08af7a5f9386a43919eda9de33ffda16b44eb11f3b313e6822243770e9763 \ --hash=sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436 \ diff --git a/v2/pubsub-binary-to-bigquery/src/main/resources/requirements.txt b/v2/pubsub-binary-to-bigquery/src/main/resources/requirements.txt index 4095f3e5bc..ec9e39172c 100644 --- a/v2/pubsub-binary-to-bigquery/src/main/resources/requirements.txt +++ b/v2/pubsub-binary-to-bigquery/src/main/resources/requirements.txt @@ -27,38 +27,32 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -apache-beam[dataframe,gcp,test,yaml]==2.60.0 \ - --hash=sha256:04644d4021522674b56c32b199c8ca89ee9ffef6eee1b21a29a6b8cd0fdfc16c \ - --hash=sha256:0594dff34776f4929aa24b35b677d5b2688c6e565e6a32921fad7d7c6a4063a0 \ - --hash=sha256:10e4ecd11e7b3c9149e3704b6fc3a5f98ae63c889167681e4e18d9633d34957c \ - --hash=sha256:12f292ee820e37ba0bf47ed54173cb6d15cce24beaa28a676e85ddb3f0a55263 \ - --hash=sha256:239b02a82d8abd0400e8f2316b2b4ee08092c898d3eac36ffa7e3a632612fbb4 \ - --hash=sha256:354f8c058b15608d1a79da55edc4f8fa724fff92269db02a81ccb3dfa82e08a5 \ - --hash=sha256:3728ee7c0e9efcd9e1323ccf5dbebf5d56f7ce0fcc5ec78e63747ec4d7496c44 \ - --hash=sha256:398dc3dc9e7079290548be96102b5bb9179c922534ef166bf22478b6b477b42c \ - --hash=sha256:401593f23e85d5531754ca0fb5bb4e251959dcd1b2864e5a28844004ab1a7231 \ - --hash=sha256:4252bee4ec51effe858aa3ac17ca09520a7dedfe4456a23dd286332e501ea7b9 \ - --hash=sha256:4297dd4d13869f14192ae257527cb8d499273509e6bc166ac92eb0a8ec25f1fe \ - --hash=sha256:447ff21a0eb76dfa78a6164e752a1c1205c055f22145178048cd619dada4e72f \ - --hash=sha256:482ee5caad2244472d7572c555a777e459207770483775d6a694c3ef2f9e5e45 \ - --hash=sha256:4bd24eedddbdd7980e698ab0f588e2e9d641c434f586970a57164259f9ce2db4 \ - --hash=sha256:6062b07b25c766cb8c7a94a64755093a7bc7e7aa0ff39f0f44d13a47d5696619 \ - --hash=sha256:68121213c675ebf23c4d1e0c7f3e60f2db7648e2d7da6323efd62a684b2a64b6 \ - --hash=sha256:7b7e17ff038795f96b64a1e0261338aba2d36857324bd582fedbe05d41542a81 \ - --hash=sha256:8064c7896361a5451371c2d4b03660ba85f673ce00e4c57fed5e355f268dca9b \ - --hash=sha256:83c54241552e35174ad44e90915aebd251beee31f9176a16ec931e8ce65c882d \ - --hash=sha256:863a67bbd0899deefdb1cc7c5b7c03a3f98aae237b0f5fb6311beed2901102e2 \ - --hash=sha256:875f8755842a38db7cda27dfa7f92fe4ef004aaaa49d8b23721193c2010076ef \ - --hash=sha256:951b6a7e49dacef27181f6d1b15db368d9584e0a802dd61cd9fab949ce339ee8 \ - --hash=sha256:aad7ca6f38e7e82bc28ed8473a4649d24249f438543ed6879776d8ef5dc2e743 \ - --hash=sha256:b043748caaeb82655982479b39189f76c1948903230e7cd33057efc66737003f \ - --hash=sha256:ba0404ddf8f95206328993f3db1b50f06d3034bc84c4440c4df4ce86060cee73 \ - --hash=sha256:bcc4142e0465dcfecbec6908896aa4b43ae8d4ca0b3fa88a23fe6d4ee5033b96 \ - --hash=sha256:c7ab3edbac04723bbc3d8c849d824f7bab63c969c14dc0f876d894d06787919a \ - --hash=sha256:f5543ff7c6c64afbded02e9d99b5f142efc12ed5cefefa070a6914b3641d7b02 \ - --hash=sha256:f56d680c2129dcbb5d96439921a1f14a2a072db904fa96ed2c52bef6daa8559c \ - --hash=sha256:fbe467dc7800e257306d43761b61aeaaead8b8ac8ab35d0b296cf4ec9e1d71de \ - --hash=sha256:ffae157ecde933f4dca4c13775ad3c0e7fc846c6b538965bd9222d4bf7ccfa9a +apache-beam[dataframe,gcp,test,yaml]==2.62.0 \ + --hash=sha256:02d33aae5a4cc3acc7a2fb86e3632cdbd240522256778e1da0f6b9192eeef91e \ + --hash=sha256:04c58ef6827142b39a4c95f3403e388646fde8d88e823c7d4f624b45dea459fa \ + --hash=sha256:04e99ef0fd74b645971549a16576f41a7a3c7a5360b67723a906334d70d04be3 \ + --hash=sha256:147491dfde40c9ac0353899fc6632d92d24663c8f9d44ea30157e66752b6f54c \ + --hash=sha256:158bce813662a39e2ee504273cc5fc492779703b8f596ef1a3210a62a5263b10 \ + --hash=sha256:1e8f741de5c66122f5c97f8a6838ab7bfdbe7bbbbdadeef9f91bd0561487c26d \ + --hash=sha256:3489d45fb04d542061af8f59b908e7a0168da5aacded308bb7825fd43f7068c7 \ + --hash=sha256:34d353f5a9aeda4a3ee484907b14e2942b9e8f7f8a112b5a98d69663ed4ef68a \ + --hash=sha256:3d5112494e4e672af404a8cb13dce3c12e3e11e5aaae7d78bc1b2c640f1e8c05 \ + --hash=sha256:5044f2e2608d8e52b8267ec0fba250814388dd97c3ca7107d7cad0897895cbb8 \ + --hash=sha256:5e5584dd4d68e1f1ace4c1775707afb5309852332ecc4975344bcc8a300d7399 \ + --hash=sha256:8843a8306c0548c0224e7f0567de9494552068bd76101b6cc4bef445c3ffa495 \ + --hash=sha256:8b79b8dc2968321d433d8d353a5b4c86c63e3a16cd9aced62c73e8ce3269d3cb \ + --hash=sha256:b158b0c0d8a18e0f0b5c32031b61c51e19b12825312d8c01533c61d65b5fbda4 \ + --hash=sha256:b61f298a43b7672604a4d3c4f3eef413f6c9b55aeadcacd06631d6ccc319aee8 \ + --hash=sha256:b771ad9202816ddd1d887cbe1083b9711b8b3593c0a78f2e85a1d7f5c0adbdac \ + --hash=sha256:b9d97df88b9b9e4585fff5ee09959d76b0ab596bb78ae986fac8c04bf8cc78db \ + --hash=sha256:bc5dd62c005526c82d6ed1ffde7324e5347c1ff417061b5e63c330dc02e9e601 \ + --hash=sha256:c4d5a43bb601520ce5ba30505a1597d2f4f0a02fbf56ca78213565b4c0ae7420 \ + --hash=sha256:c7c1632a29ed785a93e5f9c8bed3e18d962789d06c8acc943f6faf9e24a177b7 \ + --hash=sha256:c947f13bf6b8f7904994a3d846fe71ea2b28991373316c205987a42da8df4084 \ + --hash=sha256:e24db3b37969353f0fdf8c13f2127a391d4483dcb81b2cf6211d37108bd8599a \ + --hash=sha256:e65d11b8ac8eb84cbff56fe2aefb6da6449aee07339755138c8bce3d4d7df206 \ + --hash=sha256:f28d8a79552fceeaaf0ed0b0f2b41b2143e1013745a5847d7defbb4a6ebfe9a1 \ + --hash=sha256:f30e40163a23a64a4469ca2c74674eff7b1b5fcfd49c1461565c4aeda978a096 # via -r python/default_base_yaml_requirements.txt attrs==24.2.0 \ --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ @@ -1072,74 +1066,79 @@ protobuf==4.25.5 \ # grpc-google-iam-v1 # grpcio-status # proto-plus -psycopg2-binary==2.9.10 \ - --hash=sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff \ - --hash=sha256:056470c3dc57904bbf63d6f534988bafc4e970ffd50f6271fc4ee7daad9498a5 \ - --hash=sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f \ - --hash=sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5 \ - --hash=sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0 \ - --hash=sha256:19721ac03892001ee8fdd11507e6a2e01f4e37014def96379411ca99d78aeb2c \ - --hash=sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c \ - --hash=sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341 \ - --hash=sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f \ - --hash=sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7 \ - --hash=sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d \ - --hash=sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007 \ - --hash=sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92 \ - --hash=sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb \ - --hash=sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5 \ - --hash=sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5 \ - --hash=sha256:3216ccf953b3f267691c90c6fe742e45d890d8272326b4a8b20850a03d05b7b8 \ - --hash=sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1 \ - --hash=sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68 \ - --hash=sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73 \ - --hash=sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1 \ - --hash=sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53 \ - --hash=sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d \ - --hash=sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906 \ - --hash=sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0 \ - --hash=sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2 \ - --hash=sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a \ - --hash=sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b \ - --hash=sha256:5c370b1e4975df846b0277b4deba86419ca77dbc25047f535b0bb03d1a544d44 \ - --hash=sha256:6b269105e59ac96aba877c1707c600ae55711d9dcd3fc4b5012e4af68e30c648 \ - --hash=sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7 \ - --hash=sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f \ - --hash=sha256:73aa0e31fa4bb82578f3a6c74a73c273367727de397a7a0f07bd83cbea696baa \ - --hash=sha256:7559bce4b505762d737172556a4e6ea8a9998ecac1e39b5233465093e8cee697 \ - --hash=sha256:79625966e176dc97ddabc142351e0409e28acf4660b88d1cf6adb876d20c490d \ - --hash=sha256:7a813c8bdbaaaab1f078014b9b0b13f5de757e2b5d9be6403639b298a04d218b \ - --hash=sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526 \ - --hash=sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4 \ - --hash=sha256:7f5d859928e635fa3ce3477704acee0f667b3a3d3e4bb109f2b18d4005f38287 \ - --hash=sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e \ - --hash=sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673 \ - --hash=sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0 \ - --hash=sha256:8aabf1c1a04584c168984ac678a668094d831f152859d06e055288fa515e4d30 \ - --hash=sha256:8aecc5e80c63f7459a1a2ab2c64df952051df196294d9f739933a9f6687e86b3 \ - --hash=sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e \ - --hash=sha256:8de718c0e1c4b982a54b41779667242bc630b2197948405b7bd8ce16bcecac92 \ - --hash=sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a \ - --hash=sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c \ - --hash=sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8 \ - --hash=sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909 \ - --hash=sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47 \ - --hash=sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864 \ - --hash=sha256:d00924255d7fc916ef66e4bf22f354a940c67179ad3fd7067d7a0a9c84d2fbfc \ - --hash=sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00 \ - --hash=sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb \ - --hash=sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539 \ - --hash=sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b \ - --hash=sha256:e8b58f0a96e7a1e341fc894f62c1177a7c83febebb5ff9123b579418fdc8a481 \ - --hash=sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5 \ - --hash=sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4 \ - --hash=sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64 \ - --hash=sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392 \ - --hash=sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4 \ - --hash=sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1 \ - --hash=sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1 \ - --hash=sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567 \ - --hash=sha256:ffe8ed017e4ed70f68b7b371d84b7d4a790368db9203dfc2d222febd3a9c8863 +psycopg2-binary==2.9.9 \ + --hash=sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9 \ + --hash=sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77 \ + --hash=sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e \ + --hash=sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84 \ + --hash=sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3 \ + --hash=sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2 \ + --hash=sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67 \ + --hash=sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876 \ + --hash=sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152 \ + --hash=sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f \ + --hash=sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a \ + --hash=sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6 \ + --hash=sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503 \ + --hash=sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f \ + --hash=sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493 \ + --hash=sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996 \ + --hash=sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f \ + --hash=sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e \ + --hash=sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59 \ + --hash=sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94 \ + --hash=sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7 \ + --hash=sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682 \ + --hash=sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420 \ + --hash=sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae \ + --hash=sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291 \ + --hash=sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe \ + --hash=sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980 \ + --hash=sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93 \ + --hash=sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692 \ + --hash=sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119 \ + --hash=sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716 \ + --hash=sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472 \ + --hash=sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b \ + --hash=sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2 \ + --hash=sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc \ + --hash=sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c \ + --hash=sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5 \ + --hash=sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab \ + --hash=sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984 \ + --hash=sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9 \ + --hash=sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf \ + --hash=sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0 \ + --hash=sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f \ + --hash=sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212 \ + --hash=sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb \ + --hash=sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be \ + --hash=sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90 \ + --hash=sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041 \ + --hash=sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7 \ + --hash=sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860 \ + --hash=sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d \ + --hash=sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245 \ + --hash=sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27 \ + --hash=sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417 \ + --hash=sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359 \ + --hash=sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202 \ + --hash=sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0 \ + --hash=sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7 \ + --hash=sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba \ + --hash=sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1 \ + --hash=sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd \ + --hash=sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07 \ + --hash=sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98 \ + --hash=sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55 \ + --hash=sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d \ + --hash=sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972 \ + --hash=sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f \ + --hash=sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e \ + --hash=sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26 \ + --hash=sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957 \ + --hash=sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53 \ + --hash=sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52 # via apache-beam pyarrow==16.1.0 \ --hash=sha256:06ebccb6f8cb7357de85f60d5da50e83507954af617d7b05f48af1621d331c9a \ @@ -1820,7 +1819,9 @@ six==1.16.0 \ sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 - # via hypothesis + # via + # apache-beam + # hypothesis sqlalchemy==2.0.36 \ --hash=sha256:03e08af7a5f9386a43919eda9de33ffda16b44eb11f3b313e6822243770e9763 \ --hash=sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436 \ diff --git a/v2/pubsub-to-mongodb/src/main/resources/requirements.txt b/v2/pubsub-to-mongodb/src/main/resources/requirements.txt index 4095f3e5bc..ec9e39172c 100644 --- a/v2/pubsub-to-mongodb/src/main/resources/requirements.txt +++ b/v2/pubsub-to-mongodb/src/main/resources/requirements.txt @@ -27,38 +27,32 @@ annotated-types==0.7.0 \ --hash=sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53 \ --hash=sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89 # via pydantic -apache-beam[dataframe,gcp,test,yaml]==2.60.0 \ - --hash=sha256:04644d4021522674b56c32b199c8ca89ee9ffef6eee1b21a29a6b8cd0fdfc16c \ - --hash=sha256:0594dff34776f4929aa24b35b677d5b2688c6e565e6a32921fad7d7c6a4063a0 \ - --hash=sha256:10e4ecd11e7b3c9149e3704b6fc3a5f98ae63c889167681e4e18d9633d34957c \ - --hash=sha256:12f292ee820e37ba0bf47ed54173cb6d15cce24beaa28a676e85ddb3f0a55263 \ - --hash=sha256:239b02a82d8abd0400e8f2316b2b4ee08092c898d3eac36ffa7e3a632612fbb4 \ - --hash=sha256:354f8c058b15608d1a79da55edc4f8fa724fff92269db02a81ccb3dfa82e08a5 \ - --hash=sha256:3728ee7c0e9efcd9e1323ccf5dbebf5d56f7ce0fcc5ec78e63747ec4d7496c44 \ - --hash=sha256:398dc3dc9e7079290548be96102b5bb9179c922534ef166bf22478b6b477b42c \ - --hash=sha256:401593f23e85d5531754ca0fb5bb4e251959dcd1b2864e5a28844004ab1a7231 \ - --hash=sha256:4252bee4ec51effe858aa3ac17ca09520a7dedfe4456a23dd286332e501ea7b9 \ - --hash=sha256:4297dd4d13869f14192ae257527cb8d499273509e6bc166ac92eb0a8ec25f1fe \ - --hash=sha256:447ff21a0eb76dfa78a6164e752a1c1205c055f22145178048cd619dada4e72f \ - --hash=sha256:482ee5caad2244472d7572c555a777e459207770483775d6a694c3ef2f9e5e45 \ - --hash=sha256:4bd24eedddbdd7980e698ab0f588e2e9d641c434f586970a57164259f9ce2db4 \ - --hash=sha256:6062b07b25c766cb8c7a94a64755093a7bc7e7aa0ff39f0f44d13a47d5696619 \ - --hash=sha256:68121213c675ebf23c4d1e0c7f3e60f2db7648e2d7da6323efd62a684b2a64b6 \ - --hash=sha256:7b7e17ff038795f96b64a1e0261338aba2d36857324bd582fedbe05d41542a81 \ - --hash=sha256:8064c7896361a5451371c2d4b03660ba85f673ce00e4c57fed5e355f268dca9b \ - --hash=sha256:83c54241552e35174ad44e90915aebd251beee31f9176a16ec931e8ce65c882d \ - --hash=sha256:863a67bbd0899deefdb1cc7c5b7c03a3f98aae237b0f5fb6311beed2901102e2 \ - --hash=sha256:875f8755842a38db7cda27dfa7f92fe4ef004aaaa49d8b23721193c2010076ef \ - --hash=sha256:951b6a7e49dacef27181f6d1b15db368d9584e0a802dd61cd9fab949ce339ee8 \ - --hash=sha256:aad7ca6f38e7e82bc28ed8473a4649d24249f438543ed6879776d8ef5dc2e743 \ - --hash=sha256:b043748caaeb82655982479b39189f76c1948903230e7cd33057efc66737003f \ - --hash=sha256:ba0404ddf8f95206328993f3db1b50f06d3034bc84c4440c4df4ce86060cee73 \ - --hash=sha256:bcc4142e0465dcfecbec6908896aa4b43ae8d4ca0b3fa88a23fe6d4ee5033b96 \ - --hash=sha256:c7ab3edbac04723bbc3d8c849d824f7bab63c969c14dc0f876d894d06787919a \ - --hash=sha256:f5543ff7c6c64afbded02e9d99b5f142efc12ed5cefefa070a6914b3641d7b02 \ - --hash=sha256:f56d680c2129dcbb5d96439921a1f14a2a072db904fa96ed2c52bef6daa8559c \ - --hash=sha256:fbe467dc7800e257306d43761b61aeaaead8b8ac8ab35d0b296cf4ec9e1d71de \ - --hash=sha256:ffae157ecde933f4dca4c13775ad3c0e7fc846c6b538965bd9222d4bf7ccfa9a +apache-beam[dataframe,gcp,test,yaml]==2.62.0 \ + --hash=sha256:02d33aae5a4cc3acc7a2fb86e3632cdbd240522256778e1da0f6b9192eeef91e \ + --hash=sha256:04c58ef6827142b39a4c95f3403e388646fde8d88e823c7d4f624b45dea459fa \ + --hash=sha256:04e99ef0fd74b645971549a16576f41a7a3c7a5360b67723a906334d70d04be3 \ + --hash=sha256:147491dfde40c9ac0353899fc6632d92d24663c8f9d44ea30157e66752b6f54c \ + --hash=sha256:158bce813662a39e2ee504273cc5fc492779703b8f596ef1a3210a62a5263b10 \ + --hash=sha256:1e8f741de5c66122f5c97f8a6838ab7bfdbe7bbbbdadeef9f91bd0561487c26d \ + --hash=sha256:3489d45fb04d542061af8f59b908e7a0168da5aacded308bb7825fd43f7068c7 \ + --hash=sha256:34d353f5a9aeda4a3ee484907b14e2942b9e8f7f8a112b5a98d69663ed4ef68a \ + --hash=sha256:3d5112494e4e672af404a8cb13dce3c12e3e11e5aaae7d78bc1b2c640f1e8c05 \ + --hash=sha256:5044f2e2608d8e52b8267ec0fba250814388dd97c3ca7107d7cad0897895cbb8 \ + --hash=sha256:5e5584dd4d68e1f1ace4c1775707afb5309852332ecc4975344bcc8a300d7399 \ + --hash=sha256:8843a8306c0548c0224e7f0567de9494552068bd76101b6cc4bef445c3ffa495 \ + --hash=sha256:8b79b8dc2968321d433d8d353a5b4c86c63e3a16cd9aced62c73e8ce3269d3cb \ + --hash=sha256:b158b0c0d8a18e0f0b5c32031b61c51e19b12825312d8c01533c61d65b5fbda4 \ + --hash=sha256:b61f298a43b7672604a4d3c4f3eef413f6c9b55aeadcacd06631d6ccc319aee8 \ + --hash=sha256:b771ad9202816ddd1d887cbe1083b9711b8b3593c0a78f2e85a1d7f5c0adbdac \ + --hash=sha256:b9d97df88b9b9e4585fff5ee09959d76b0ab596bb78ae986fac8c04bf8cc78db \ + --hash=sha256:bc5dd62c005526c82d6ed1ffde7324e5347c1ff417061b5e63c330dc02e9e601 \ + --hash=sha256:c4d5a43bb601520ce5ba30505a1597d2f4f0a02fbf56ca78213565b4c0ae7420 \ + --hash=sha256:c7c1632a29ed785a93e5f9c8bed3e18d962789d06c8acc943f6faf9e24a177b7 \ + --hash=sha256:c947f13bf6b8f7904994a3d846fe71ea2b28991373316c205987a42da8df4084 \ + --hash=sha256:e24db3b37969353f0fdf8c13f2127a391d4483dcb81b2cf6211d37108bd8599a \ + --hash=sha256:e65d11b8ac8eb84cbff56fe2aefb6da6449aee07339755138c8bce3d4d7df206 \ + --hash=sha256:f28d8a79552fceeaaf0ed0b0f2b41b2143e1013745a5847d7defbb4a6ebfe9a1 \ + --hash=sha256:f30e40163a23a64a4469ca2c74674eff7b1b5fcfd49c1461565c4aeda978a096 # via -r python/default_base_yaml_requirements.txt attrs==24.2.0 \ --hash=sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346 \ @@ -1072,74 +1066,79 @@ protobuf==4.25.5 \ # grpc-google-iam-v1 # grpcio-status # proto-plus -psycopg2-binary==2.9.10 \ - --hash=sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff \ - --hash=sha256:056470c3dc57904bbf63d6f534988bafc4e970ffd50f6271fc4ee7daad9498a5 \ - --hash=sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f \ - --hash=sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5 \ - --hash=sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0 \ - --hash=sha256:19721ac03892001ee8fdd11507e6a2e01f4e37014def96379411ca99d78aeb2c \ - --hash=sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c \ - --hash=sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341 \ - --hash=sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f \ - --hash=sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7 \ - --hash=sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d \ - --hash=sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007 \ - --hash=sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92 \ - --hash=sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb \ - --hash=sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5 \ - --hash=sha256:30e34c4e97964805f715206c7b789d54a78b70f3ff19fbe590104b71c45600e5 \ - --hash=sha256:3216ccf953b3f267691c90c6fe742e45d890d8272326b4a8b20850a03d05b7b8 \ - --hash=sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1 \ - --hash=sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68 \ - --hash=sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73 \ - --hash=sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1 \ - --hash=sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53 \ - --hash=sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d \ - --hash=sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906 \ - --hash=sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0 \ - --hash=sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2 \ - --hash=sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a \ - --hash=sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b \ - --hash=sha256:5c370b1e4975df846b0277b4deba86419ca77dbc25047f535b0bb03d1a544d44 \ - --hash=sha256:6b269105e59ac96aba877c1707c600ae55711d9dcd3fc4b5012e4af68e30c648 \ - --hash=sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7 \ - --hash=sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f \ - --hash=sha256:73aa0e31fa4bb82578f3a6c74a73c273367727de397a7a0f07bd83cbea696baa \ - --hash=sha256:7559bce4b505762d737172556a4e6ea8a9998ecac1e39b5233465093e8cee697 \ - --hash=sha256:79625966e176dc97ddabc142351e0409e28acf4660b88d1cf6adb876d20c490d \ - --hash=sha256:7a813c8bdbaaaab1f078014b9b0b13f5de757e2b5d9be6403639b298a04d218b \ - --hash=sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526 \ - --hash=sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4 \ - --hash=sha256:7f5d859928e635fa3ce3477704acee0f667b3a3d3e4bb109f2b18d4005f38287 \ - --hash=sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e \ - --hash=sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673 \ - --hash=sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0 \ - --hash=sha256:8aabf1c1a04584c168984ac678a668094d831f152859d06e055288fa515e4d30 \ - --hash=sha256:8aecc5e80c63f7459a1a2ab2c64df952051df196294d9f739933a9f6687e86b3 \ - --hash=sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e \ - --hash=sha256:8de718c0e1c4b982a54b41779667242bc630b2197948405b7bd8ce16bcecac92 \ - --hash=sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a \ - --hash=sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c \ - --hash=sha256:b73d6d7f0ccdad7bc43e6d34273f70d587ef62f824d7261c4ae9b8b1b6af90e8 \ - --hash=sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909 \ - --hash=sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47 \ - --hash=sha256:ce5ab4bf46a211a8e924d307c1b1fcda82368586a19d0a24f8ae166f5c784864 \ - --hash=sha256:d00924255d7fc916ef66e4bf22f354a940c67179ad3fd7067d7a0a9c84d2fbfc \ - --hash=sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00 \ - --hash=sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb \ - --hash=sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539 \ - --hash=sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b \ - --hash=sha256:e8b58f0a96e7a1e341fc894f62c1177a7c83febebb5ff9123b579418fdc8a481 \ - --hash=sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5 \ - --hash=sha256:eb09aa7f9cecb45027683bb55aebaaf45a0df8bf6de68801a6afdc7947bb09d4 \ - --hash=sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64 \ - --hash=sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392 \ - --hash=sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4 \ - --hash=sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1 \ - --hash=sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1 \ - --hash=sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567 \ - --hash=sha256:ffe8ed017e4ed70f68b7b371d84b7d4a790368db9203dfc2d222febd3a9c8863 +psycopg2-binary==2.9.9 \ + --hash=sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9 \ + --hash=sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77 \ + --hash=sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e \ + --hash=sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84 \ + --hash=sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3 \ + --hash=sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2 \ + --hash=sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67 \ + --hash=sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876 \ + --hash=sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152 \ + --hash=sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f \ + --hash=sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a \ + --hash=sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6 \ + --hash=sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503 \ + --hash=sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f \ + --hash=sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493 \ + --hash=sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996 \ + --hash=sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f \ + --hash=sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e \ + --hash=sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59 \ + --hash=sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94 \ + --hash=sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7 \ + --hash=sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682 \ + --hash=sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420 \ + --hash=sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae \ + --hash=sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291 \ + --hash=sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe \ + --hash=sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980 \ + --hash=sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93 \ + --hash=sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692 \ + --hash=sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119 \ + --hash=sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716 \ + --hash=sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472 \ + --hash=sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b \ + --hash=sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2 \ + --hash=sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc \ + --hash=sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c \ + --hash=sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5 \ + --hash=sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab \ + --hash=sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984 \ + --hash=sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9 \ + --hash=sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf \ + --hash=sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0 \ + --hash=sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f \ + --hash=sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212 \ + --hash=sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb \ + --hash=sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be \ + --hash=sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90 \ + --hash=sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041 \ + --hash=sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7 \ + --hash=sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860 \ + --hash=sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d \ + --hash=sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245 \ + --hash=sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27 \ + --hash=sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417 \ + --hash=sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359 \ + --hash=sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202 \ + --hash=sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0 \ + --hash=sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7 \ + --hash=sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba \ + --hash=sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1 \ + --hash=sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd \ + --hash=sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07 \ + --hash=sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98 \ + --hash=sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55 \ + --hash=sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d \ + --hash=sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972 \ + --hash=sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f \ + --hash=sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e \ + --hash=sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26 \ + --hash=sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957 \ + --hash=sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53 \ + --hash=sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52 # via apache-beam pyarrow==16.1.0 \ --hash=sha256:06ebccb6f8cb7357de85f60d5da50e83507954af617d7b05f48af1621d331c9a \ @@ -1820,7 +1819,9 @@ six==1.16.0 \ sortedcontainers==2.4.0 \ --hash=sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88 \ --hash=sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0 - # via hypothesis + # via + # apache-beam + # hypothesis sqlalchemy==2.0.36 \ --hash=sha256:03e08af7a5f9386a43919eda9de33ffda16b44eb11f3b313e6822243770e9763 \ --hash=sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436 \ From b844b9eafb3cddf43f1a56bcfe01acaccfee8a6b Mon Sep 17 00:00:00 2001 From: Taher Lakdawala <78196491+taherkl@users.noreply.github.com> Date: Thu, 23 Jan 2025 10:32:59 +0530 Subject: [PATCH 8/8] Cassandra DML Generator - Spanner to SourceDB (#2120) * Dml integration (#53) * Added extensive UT Added extensive UT * Cassandra pr bug fixes (#57) * Cassandra Consolidate Unit Test case and Regression testing fixes (#58) * Added Mapping fixes * Added Spoltles fixes * Added Consolidated fixes * Added TODO * Addess Data and Time * Cassandra pr bug fixes (#64) * Handle TypeHandler Parsing issue fixes (#65) Co-authored-by: pawankashyapollion * Added Safe handle (#68) * Handle LocalTime For Time Data Type In Cassandra (#69) * Cassandra pr bug fixes (#70) * Handle Timestamp Fixes (#72) * Added Code Combined in a single way * Address The Unwanted Hop * Cassandra pr bug fixes (#75) * Added PR Review Comments * Remove NamesCol Dependecy as spannerTableName is same as In Given Mapping * Added spannerTableId for fetching Mapping * Removed SpannerToID and also Updated Session file with proper structure * Timestamp in milisecond * removed assertNotNull from UT wherever possible * Added Fixes * Added Note Instead of Question * -- review fixes (#78) * Added Bytes to hex to blob conversion * Handling Bytes as Binary encoded As of now * Passing Null Value to Primary Key as well for cassandra * Added UT fixes * Added UT refectoring * Reverse merge confict fixes --------- Co-authored-by: pawankashyapollion Co-authored-by: Akash Thawait --- .../v2/spanner/migrations/schema/Schema.java | 2 + .../v2/templates/constants/Constants.java | 1 - .../dbutils/dao/source/CassandraDao.java | 37 +- .../dbutils/dml/CassandraDMLGenerator.java | 416 ++++ .../dbutils/dml/CassandraTypeHandler.java | 1206 ++++------- .../processor/InputRecordProcessor.java | 25 +- .../processor/SourceProcessorFactory.java | 14 +- .../templates/models/DMLGeneratorRequest.java | 13 + .../templates/transforms/SourceWriterFn.java | 3 +- .../dbutils/dao/source/CassandraDaoTest.java | 22 + .../dml/CassandraDMLGeneratorTest.java | 925 ++++++++ .../dbutils/dml/CassandraTypeHandlerTest.java | 1856 ++++++++--------- .../processor/SourceProcessorFactoryTest.java | 4 +- .../src/test/resources/cassandraSession.json | 1064 ++++++++++ 14 files changed, 3827 insertions(+), 1761 deletions(-) create mode 100644 v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraDMLGenerator.java create mode 100644 v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraDMLGeneratorTest.java create mode 100644 v2/spanner-to-sourcedb/src/test/resources/cassandraSession.json diff --git a/v2/spanner-common/src/main/java/com/google/cloud/teleport/v2/spanner/migrations/schema/Schema.java b/v2/spanner-common/src/main/java/com/google/cloud/teleport/v2/spanner/migrations/schema/Schema.java index 55bd22b9aa..c49fcba6a3 100644 --- a/v2/spanner-common/src/main/java/com/google/cloud/teleport/v2/spanner/migrations/schema/Schema.java +++ b/v2/spanner-common/src/main/java/com/google/cloud/teleport/v2/spanner/migrations/schema/Schema.java @@ -77,6 +77,8 @@ public Schema( this.srcSchema = srcSchema; this.toSpanner = toSpanner; this.toSource = toSource; + this.srcToID = toSource; + this.spannerToID = toSpanner; this.empty = (spSchema == null || srcSchema == null); } diff --git a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/constants/Constants.java b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/constants/Constants.java index 476d199d46..35c354f267 100644 --- a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/constants/Constants.java +++ b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/constants/Constants.java @@ -75,7 +75,6 @@ public class Constants { public static final String DEFAULT_SHARD_ID = "single_shard"; public static final String SOURCE_MYSQL = "mysql"; - public static final String SOURCE_CASSANDRA = "cassandra"; // Message written to the file for filtered records diff --git a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/dao/source/CassandraDao.java b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/dao/source/CassandraDao.java index 5960a413c2..7181741de0 100644 --- a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/dao/source/CassandraDao.java +++ b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/dao/source/CassandraDao.java @@ -19,10 +19,10 @@ import com.datastax.oss.driver.api.core.cql.BoundStatement; import com.datastax.oss.driver.api.core.cql.PreparedStatement; import com.google.cloud.teleport.v2.templates.dbutils.connection.IConnectionHelper; +import com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler; import com.google.cloud.teleport.v2.templates.exceptions.ConnectionException; import com.google.cloud.teleport.v2.templates.models.DMLGeneratorResponse; import com.google.cloud.teleport.v2.templates.models.PreparedStatementGeneratedResponse; -import com.google.cloud.teleport.v2.templates.models.PreparedStatementValueObject; public class CassandraDao implements IDao { private final String cassandraUrl; @@ -38,22 +38,25 @@ public CassandraDao( @Override public void write(DMLGeneratorResponse dmlGeneratorResponse) throws Exception { - try (CqlSession session = - (CqlSession) - connectionHelper.getConnection(this.cassandraUrl)) { // Ensure connection is obtained - if (session == null) { - throw new ConnectionException("Connection is null"); - } - PreparedStatementGeneratedResponse preparedStatementGeneratedResponse = - (PreparedStatementGeneratedResponse) dmlGeneratorResponse; - String dmlStatement = preparedStatementGeneratedResponse.getDmlStatement(); - PreparedStatement preparedStatement = session.prepare(dmlStatement); - BoundStatement boundStatement = - preparedStatement.bind( - preparedStatementGeneratedResponse.getValues().stream() - .map(PreparedStatementValueObject::value) - .toArray()); - session.execute(boundStatement); + CqlSession session = (CqlSession) connectionHelper.getConnection(this.cassandraUrl); + if (session == null) { + throw new ConnectionException("Connection is null"); } + PreparedStatementGeneratedResponse preparedStatementGeneratedResponse = + (PreparedStatementGeneratedResponse) dmlGeneratorResponse; + String dmlStatement = preparedStatementGeneratedResponse.getDmlStatement(); + PreparedStatement preparedStatement = session.prepare(dmlStatement); + BoundStatement boundStatement = + preparedStatement.bind( + preparedStatementGeneratedResponse.getValues().stream() + .map( + v -> { + if (v.value() == CassandraTypeHandler.NullClass.INSTANCE) { + return null; + } + return CassandraTypeHandler.castToExpectedType(v.dataType(), v.value()); + }) + .toArray()); + session.execute(boundStatement); } } diff --git a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraDMLGenerator.java b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraDMLGenerator.java new file mode 100644 index 0000000000..990acfc64d --- /dev/null +++ b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraDMLGenerator.java @@ -0,0 +1,416 @@ +/* + * Copyright (C) 2025 Google LLC + * + * Licensed 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 com.google.cloud.teleport.v2.templates.dbutils.dml; + +import com.google.cloud.teleport.v2.spanner.migrations.schema.ColumnPK; +import com.google.cloud.teleport.v2.spanner.migrations.schema.Schema; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SourceColumnDefinition; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SourceTable; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SpannerColumnDefinition; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SpannerTable; +import com.google.cloud.teleport.v2.templates.models.DMLGeneratorRequest; +import com.google.cloud.teleport.v2.templates.models.DMLGeneratorResponse; +import com.google.cloud.teleport.v2.templates.models.PreparedStatementGeneratedResponse; +import com.google.cloud.teleport.v2.templates.models.PreparedStatementValueObject; +import com.google.common.collect.ImmutableMap; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A generator for creating Data Manipulation Language (DML) statements for Cassandra. Implements + * the {@link IDMLGenerator} interface to handle various types of DML operations, such as insert, + * update, delete, and upsert. + * + *

This class is designed to construct Cassandra-specific DML statements by mapping input data + * and schema information to query formats that align with Cassandra's syntax and structure. It also + * validates primary keys, handles data type conversions, and manages timestamps in queries. + * + *

Key Responsibilities: + * + *

    + *
  • Generating upsert statements for inserting or updating records. + *
  • Creating delete statements for rows identified by primary key values. + *
  • Mapping input data to Cassandra-compatible column values. + *
  • Handling specific data types and ensuring query compatibility with Cassandra. + *
+ * + *

Usage Example: + * + *

{@code
+ * IDMLGenerator generator = new CassandraDMLGenerator();
+ * DMLGeneratorResponse response = generator.getDMLStatement(dmlGeneratorRequest);
+ * }
+ * + * @see IDMLGenerator + */ +public class CassandraDMLGenerator implements IDMLGenerator { + private static final Logger LOG = LoggerFactory.getLogger(CassandraDMLGenerator.class); + + /** + * @param dmlGeneratorRequest the request containing necessary information to construct the DML + * statement, including modification type, table schema, new values, and key values. + * @return DMLGeneratorResponse + */ + @Override + public DMLGeneratorResponse getDMLStatement(DMLGeneratorRequest dmlGeneratorRequest) { + if (dmlGeneratorRequest == null) { + LOG.warn("DMLGeneratorRequest is null. Cannot process the request."); + return new DMLGeneratorResponse(""); + } + + String spannerTableName = dmlGeneratorRequest.getSpannerTableName(); + Schema schema = dmlGeneratorRequest.getSchema(); + + if (schema == null + || schema.getSpannerToID() == null + || schema.getSpSchema() == null + || schema.getSrcSchema() == null) { + LOG.warn("Schema is invalid or incomplete for table: {}", spannerTableName); + return new DMLGeneratorResponse(""); + } + SpannerTable spannerTable = schema.getSpSchema().get(spannerTableName); + if (spannerTable == null) { + LOG.warn("Spanner table {} not found. Dropping the record.", spannerTableName); + return new DMLGeneratorResponse(""); + } + + SourceTable sourceTable = schema.getSrcSchema().get(spannerTableName); + if (sourceTable == null) { + LOG.warn( + "Source table {} not found for Spanner table Name: {}", + spannerTableName, + spannerTableName); + return new DMLGeneratorResponse(""); + } + + if (sourceTable.getPrimaryKeys() == null || sourceTable.getPrimaryKeys().length == 0) { + LOG.warn( + "Cannot reverse replicate table {} without primary key. Skipping the record.", + sourceTable.getName()); + return new DMLGeneratorResponse(""); + } + + Map> pkColumnNameValues = + getPkColumnValues( + spannerTable, + sourceTable, + dmlGeneratorRequest.getNewValuesJson(), + dmlGeneratorRequest.getKeyValuesJson(), + dmlGeneratorRequest.getSourceDbTimezoneOffset()); + if (pkColumnNameValues == null) { + LOG.warn( + "Failed to generate primary key values for table {}. Skipping the record.", + sourceTable.getName()); + return new DMLGeneratorResponse(""); + } + java.sql.Timestamp timestamp = dmlGeneratorRequest.getCommitTimestamp().toSqlTimestamp(); + String modType = dmlGeneratorRequest.getModType(); + return generateDMLResponse( + spannerTable, sourceTable, dmlGeneratorRequest, pkColumnNameValues, timestamp, modType); + } + + /** + * Generates a DML response based on the given modification type (INSERT, UPDATE, or DELETE). + * + *

This method processes the data from SpannerTable, SourceTable, and DMLGeneratorRequest to + * construct a corresponding CQL statement (INSERT, UPDATE, or DELETE) for Cassandra. The + * statement is generated based on the modification type and includes the appropriate primary key + * and column values, along with an optional timestamp. + * + * @param spannerTable the SpannerTable object containing schema information of the Spanner table + * @param sourceTable the SourceTable object containing details of the source table (e.g., name) + * @param dmlGeneratorRequest the request object containing new and key value data in JSON format + * @param pkColumnNameValues a map of primary key column names and their corresponding value + * objects + * @param timestamp the optional timestamp to be included in the Cassandra statement (can be null) + * @param modType the type of modification to perform, either "INSERT", "UPDATE", or "DELETE" + * @return DMLGeneratorResponse the response containing the generated CQL statement and bound + * values + * @throws IllegalArgumentException if the modType is unsupported or if any required data is + * invalid + * @implNote The method uses the following logic: - Combines primary key values and column values + * into a single list of entries. - Depending on the modType: - For "INSERT" or "UPDATE", + * calls {@link #getUpsertStatementCQL}. - For "DELETE", calls {@link #getDeleteStatementCQL}. + * - For unsupported modType values, logs an error and returns an empty response. + */ + private static DMLGeneratorResponse generateDMLResponse( + SpannerTable spannerTable, + SourceTable sourceTable, + DMLGeneratorRequest dmlGeneratorRequest, + Map> pkColumnNameValues, + java.sql.Timestamp timestamp, + String modType) { + Map> columnNameValues = + getColumnValues( + spannerTable, + sourceTable, + dmlGeneratorRequest.getNewValuesJson(), + dmlGeneratorRequest.getKeyValuesJson(), + dmlGeneratorRequest.getSourceDbTimezoneOffset()); + Map> allColumnNamesAndValues = + ImmutableMap.>builder() + .putAll(pkColumnNameValues) + .putAll(columnNameValues) + .build(); + switch (modType) { + case "INSERT": + case "UPDATE": + return getUpsertStatementCQL(sourceTable.getName(), timestamp, allColumnNamesAndValues); + case "DELETE": + return getDeleteStatementCQL(sourceTable.getName(), timestamp, allColumnNamesAndValues); + default: + LOG.error("Unsupported modType: {} for table {}", modType, spannerTable.getName()); + return new DMLGeneratorResponse(""); + } + } + + /** + * Constructs an upsert (insert or update) CQL statement for a Cassandra or similar database using + * the provided table name, timestamp, column values, and primary key values. + * + * @param tableName the name of the table to which the upsert statement applies. + * @param timestamp the timestamp (in java.sql.Timestamp) to use for the operation. + * @param allColumnNamesAndValues a map of column names and their corresponding prepared statement + * value objects for non-primary key columns. + * @return a {@link DMLGeneratorResponse} containing the generated CQL statement and a list of + * values to be used with the prepared statement. + *

This method: 1. Iterates through the primary key and column values, appending column + * names and placeholders to the generated CQL statement. 2. Constructs the `INSERT INTO` CQL + * statement with the provided table name, columns, and placeholders. 3. Appends a `USING + * TIMESTAMP` clause to include the provided timestamp in the statement. 4. Creates a list of + * values to bind to the placeholders in the prepared statement. + *

The returned response contains the complete prepared CQL statement and the values + * required to execute it. + */ + private static DMLGeneratorResponse getUpsertStatementCQL( + String tableName, + java.sql.Timestamp timestamp, + Map> allColumnNamesAndValues) { + + String escapedTableName = "\"" + tableName.replace("\"", "\"\"") + "\""; + + String allColumns = + allColumnNamesAndValues.keySet().stream() + .map(columnName -> "\"" + columnName.replace("\"", "\"\"") + "\"") + .collect(Collectors.joining(", ")); + + String placeholders = + allColumnNamesAndValues.keySet().stream() + .map(columnName -> "?") + .collect(Collectors.joining(", ")); + + List> values = + new ArrayList<>(allColumnNamesAndValues.values()); + + PreparedStatementValueObject timestampObj = + PreparedStatementValueObject.create("USING_TIMESTAMP", timestamp.getTime()); + values.add(timestampObj); + + String preparedStatement = + String.format( + "INSERT INTO %s (%s) VALUES (%s) USING TIMESTAMP ?", + escapedTableName, allColumns, placeholders); + + return new PreparedStatementGeneratedResponse(preparedStatement, values); + } + + /** + * Constructs a delete statement in CQL (Cassandra Query Language) using the provided table name, + * primary key values, and timestamp. + * + * @param tableName the name of the table from which records will be deleted. + * @param timestamp the timestamp (in java.sql.Timestamp) to use for the delete operation. + * @return a {@link DMLGeneratorResponse} containing the generated CQL delete statement and a list + * of values to bind to the prepared statement. + *

This method: 1. Iterates through the provided primary key column values, appending + * conditions to the WHERE clause of the CQL delete statement. 2. Constructs the `DELETE FROM` + * CQL statement with the specified table name, primary key conditions, and a `USING + * TIMESTAMP` clause. 3. Creates a list of values to be used with the prepared statement, + * including the timestamp. + *

If no primary key column values are provided, an empty WHERE clause is generated. An + * exception may be thrown if any value type does not match the expected type. + */ + private static DMLGeneratorResponse getDeleteStatementCQL( + String tableName, + java.sql.Timestamp timestamp, + Map> allColumnNamesAndValues) { + + String escapedTableName = "\"" + tableName.replace("\"", "\"\"") + "\""; + + String deleteConditions = + allColumnNamesAndValues.keySet().stream() + .map(columnName -> "\"" + columnName.replace("\"", "\"\"") + "\" = ?") + .collect(Collectors.joining(" AND ")); + + List> values = + new ArrayList<>(allColumnNamesAndValues.values()); + + if (timestamp != null) { + PreparedStatementValueObject timestampObj = + PreparedStatementValueObject.create("USING_TIMESTAMP", timestamp.getTime()); + values.add(0, timestampObj); + } + + String preparedStatement = + String.format( + "DELETE FROM %s USING TIMESTAMP ? WHERE %s", escapedTableName, deleteConditions); + + return new PreparedStatementGeneratedResponse(preparedStatement, values); + } + + /** + * Extracts the column values from the source table based on the provided Spanner schema, new + * values, and key values JSON objects. + * + * @param spannerTable the Spanner table schema. + * @param sourceTable the source table schema. + * @param newValuesJson the JSON object containing new values for columns. + * @param keyValuesJson the JSON object containing key values for columns. + * @param sourceDbTimezoneOffset the timezone offset of the source database. + * @return a map of column names to their corresponding prepared statement value objects. + *

This method: 1. Iterates over the non-primary key column definitions in the source table + * schema. 2. Maps each column in the source table schema to its corresponding column in the + * Spanner schema. 3. Checks if the column values exist in the `keyValuesJson` or + * `newValuesJson` and retrieves the appropriate value. 4. Skips columns that do not exist in + * any of the JSON objects or are marked as null. + */ + private static Map> getColumnValues( + SpannerTable spannerTable, + SourceTable sourceTable, + JSONObject newValuesJson, + JSONObject keyValuesJson, + String sourceDbTimezoneOffset) { + Map> response = new HashMap<>(); + Set sourcePKs = sourceTable.getPrimaryKeySet(); + for (Map.Entry entry : sourceTable.getColDefs().entrySet()) { + SourceColumnDefinition sourceColDef = entry.getValue(); + + String colName = sourceColDef.getName(); + if (sourcePKs.contains(colName)) { + continue; // we only need non-primary keys + } + + String colId = entry.getKey(); + SpannerColumnDefinition spannerColDef = spannerTable.getColDefs().get(colId); + if (spannerColDef == null) { + continue; + } + String spannerColumnName = spannerColDef.getName(); + PreparedStatementValueObject columnValue; + if (keyValuesJson.has(spannerColumnName)) { + columnValue = + getMappedColumnValue( + spannerColDef, sourceColDef, keyValuesJson, sourceDbTimezoneOffset); + } else if (newValuesJson.has(spannerColumnName)) { + columnValue = + getMappedColumnValue( + spannerColDef, sourceColDef, newValuesJson, sourceDbTimezoneOffset); + } else { + continue; + } + + response.put(sourceColDef.getName(), columnValue); + } + + return response; + } + + /** + * Extracts the primary key column values from the source table based on the provided Spanner + * schema, new values, and key values JSON objects. + * + * @param spannerTable the Spanner table schema. + * @param sourceTable the source table schema. + * @param newValuesJson the JSON object containing new values for columns. + * @param keyValuesJson the JSON object containing key values for columns. + * @param sourceDbTimezoneOffset the timezone offset of the source database. + * @return a map of primary key column names to their corresponding prepared statement value + * objects, or null if a required column is missing. + *

This method: 1. Iterates over the primary key definitions in the source table schema. 2. + * Maps each primary key column in the source table schema to its corresponding column in the + * Spanner schema. 3. Checks if the primary key column values exist in the `keyValuesJson` or + * `newValuesJson` and retrieves the appropriate value. 4. Returns null if any required + * primary key column is missing in the JSON objects. + */ + private static Map> getPkColumnValues( + SpannerTable spannerTable, + SourceTable sourceTable, + JSONObject newValuesJson, + JSONObject keyValuesJson, + String sourceDbTimezoneOffset) { + Map> response = new HashMap<>(); + ColumnPK[] sourcePKs = sourceTable.getPrimaryKeys(); + + for (ColumnPK currentSourcePK : sourcePKs) { + String colId = currentSourcePK.getColId(); + SourceColumnDefinition sourceColDef = sourceTable.getColDefs().get(colId); + SpannerColumnDefinition spannerColDef = spannerTable.getColDefs().get(colId); + if (spannerColDef == null) { + LOG.warn( + "The corresponding primary key column {} was not found in Spanner", + sourceColDef.getName()); + return null; + } + String spannerColumnName = spannerColDef.getName(); + PreparedStatementValueObject columnValue; + if (keyValuesJson.has(spannerColumnName)) { + columnValue = + getMappedColumnValue( + spannerColDef, sourceColDef, keyValuesJson, sourceDbTimezoneOffset); + } else if (newValuesJson.has(spannerColumnName)) { + columnValue = + getMappedColumnValue( + spannerColDef, sourceColDef, newValuesJson, sourceDbTimezoneOffset); + } else { + LOG.warn("The column {} was not found in input record", spannerColumnName); + return null; + } + + response.put(sourceColDef.getName(), columnValue); + } + + return response; + } + + /** + * Maps a column value from the source table to its corresponding Spanner column value based on + * their respective definitions. + * + * @param spannerColDef the Spanner column definition. + * @param sourceColDef the source column definition. + * @param valuesJson the JSON object containing column values. + * @param sourceDbTimezoneOffset the timezone offset of the source database. + * @return a {@link PreparedStatementValueObject} containing the mapped value for the column. + *

This method: 1. Retrieves the value of the column from the JSON object. 2. Converts the + * value to the appropriate type based on the Spanner and source column definitions. 3. Uses a + * type handler to map the value if necessary. + */ + private static PreparedStatementValueObject getMappedColumnValue( + SpannerColumnDefinition spannerColDef, + SourceColumnDefinition sourceColDef, + JSONObject valuesJson, + String sourceDbTimezoneOffset) { + return CassandraTypeHandler.getColumnValueByType( + spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); + } +} diff --git a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraTypeHandler.java b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraTypeHandler.java index 54edd291dd..39e51d63ab 100644 --- a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraTypeHandler.java +++ b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraTypeHandler.java @@ -15,102 +15,111 @@ */ package com.google.cloud.teleport.v2.templates.dbutils.dml; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SourceColumnDefinition; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SpannerColumnDefinition; +import com.google.cloud.teleport.v2.templates.models.PreparedStatementValueObject; import com.google.common.net.InetAddresses; +import java.math.BigDecimal; import java.math.BigInteger; import java.net.InetAddress; import java.nio.ByteBuffer; -import java.sql.Timestamp; import java.time.Duration; import java.time.Instant; import java.time.LocalDate; +import java.time.LocalTime; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoField; +import java.time.temporal.TemporalAccessor; import java.util.ArrayList; -import java.util.Date; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; -import java.util.stream.Collectors; +import org.apache.commons.lang3.BooleanUtils; import org.json.JSONArray; -import org.json.JSONException; import org.json.JSONObject; - -class CassandraTypeHandler { +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CassandraTypeHandler { + private static final Logger LOG = LoggerFactory.getLogger(CassandraTypeHandler.class); + + /** + * A singleton class representing a null or empty state. + * + *

This class cannot be instantiated directly, and its single instance is accessed via the + * {@link #INSTANCE} field. It provides a custom {@link #toString()} implementation that returns + * the string representation "NULL_CLASS". This can be used to signify a special state where an + * object is not present or explicitly set to null. + */ + public static final class NullClass { + + /** + * Private constructor to prevent instantiation of the NULL_CLASS. + * + *

This ensures that only one instance of the NULL_CLASS exists, following the singleton + * pattern. + */ + private NullClass() {} + + /** + * The singleton instance of the NULL_CLASS. + * + *

This instance can be accessed statically via this field to represent a "null" or empty + * value in various contexts. + */ + public static final NullClass INSTANCE = new NullClass(); + + /** + * Returns the string representation of the NULL_CLASS instance. + * + * @return the string "NULL_CLASS" + */ + @Override + public String toString() { + return "NULL_CLASS"; + } + } @FunctionalInterface - public interface TypeParser { - T parse(Object value); + private interface HandlerSupplier { + + /** + * Supplies a value of type {@code T}. + * + * @return A value of type {@code T}. + * @throws Exception If an error occurs while supplying the value. + */ + T get() throws Exception; } /** - * Converts a {@link String} to an ASCII representation for Cassandra's {@link String} or other - * ASCII-based types. + * Converts the provided {@link Object} value to a {@link BigInteger} representing a Cassandra + * varint. * - *

This method ensures that the string contains only valid ASCII characters (0-127). If any - * non-ASCII characters are found, an exception is thrown. + *

This method checks the type of the provided {@code value}. If it is a string, it tries to + * convert it to a {@link BigInteger}. If it is a byte array, it interprets it as a varint and + * converts it to a {@link BigInteger}. If the value is a {@link ByteBuffer}, it converts the + * content of the buffer to a byte array and then to a {@link BigInteger}. If the value is neither + * a valid number string, byte array, nor a {@link ByteBuffer}, it throws an {@link + * IllegalArgumentException}. * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing all the key-value pairs for the current - * incoming stream. - * @return A {@link String} representing the ASCII value for the column in Cassandra. - * @throws IllegalArgumentException If the string contains non-ASCII characters. + * @param value The value to be converted to a {@link BigInteger}. This could either be a string + * representing a number, a byte array representing a varint, or a {@link ByteBuffer}. + * @return A {@link BigInteger} object representing the varint value. + * @throws IllegalArgumentException If the value is neither a valid number string, byte array, nor + * a valid {@link ByteBuffer} for varint representation. */ - public static String handleCassandraAsciiType(String colName, JSONObject valuesJson) { - Object value = valuesJson.get(colName); - if (value instanceof String) { - String stringValue = (String) value; - if (isAscii(stringValue)) { - return stringValue; - } else { - throw new IllegalArgumentException( - "Invalid ASCII format for column: " - + colName - + ". String contains non-ASCII characters."); - } - } - return null; - } - - /** - * Generates a {@link BigInteger} based on the provided {@link CassandraTypeHandler}. - * - *

This method fetches the value associated with the given column name ({@code colName}) from - * the {@code valuesJson} object, and converts it to a {@link BigInteger}. The value can either be - * a string representing a number or a binary representation of a large integer (varint). - * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing all the key-value pairs for the current - * incoming stream. - * @return A {@link BigInteger} object representing the varint value from the Cassandra data. - * @throws IllegalArgumentException If the value is not a valid format for varint (neither a valid - * number string nor a byte array). - */ - public static BigInteger handleCassandraVarintType(String colName, JSONObject valuesJson) { - Object value = valuesJson.get(colName); - - if (value instanceof String) { - try { - return new BigInteger((String) value); - } catch (NumberFormatException e) { - throw new IllegalArgumentException( - "Invalid varint format (string) for column: " + colName, e); - } - } else if (value instanceof byte[]) { - try { - return new BigInteger((byte[]) value); - } catch (Exception e) { - throw new IllegalArgumentException( - "Invalid varint format (byte array) for column: " + colName, e); - } - } else { - return null; - } + private static BigInteger handleCassandraVarintType(String value) { + return new BigInteger(value); } /** @@ -120,108 +129,42 @@ public static BigInteger handleCassandraVarintType(String colName, JSONObject va * column name {@code colName}, and converts it into a {@link Duration} object. The string value * should be in the ISO-8601 duration format (e.g., "PT20.345S"). * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing all the key-value pairs for the current - * incoming stream. + * @param durationString - The column value used to fetched from {@code valuesJson}. * @return A {@link Duration} object representing the duration value from the Cassandra data. * @throws IllegalArgumentException if the value is not a valid duration string. */ - public static Duration handleCassandraDurationType(String colName, JSONObject valuesJson) { - String durationString = valuesJson.optString(colName, null); - if (durationString == null) { - return null; - } + private static Duration handleCassandraDurationType(String durationString) { try { return Duration.parse(durationString); } catch (Exception e) { - throw new IllegalArgumentException("Invalid duration format for column: " + colName, e); + throw new IllegalArgumentException("Invalid duration format for: " + durationString, e); } } /** * Generates a Type based on the provided {@link CassandraTypeHandler}. * - * @param colName - which is used to fetch Key from valueJSON. - * @param valuesJson - contains all the key value for current incoming stream. + * @param inetString - which is used to generate InetAddress. * @return a {@link InetAddress} object containing InetAddress as value represented in cassandra * type. */ - public static InetAddress handleCassandraInetAddressType(String colName, JSONObject valuesJson) { - String inetString = valuesJson.optString(colName, null); - if (inetString == null) { - return null; - } + private static InetAddress handleCassandraInetAddressType(String inetString) { try { return InetAddresses.forString(inetString); } catch (IllegalArgumentException e) { - throw new IllegalArgumentException("Invalid IP address format for column: " + colName, e); - } - } - - /** - * Generates a Type based on the provided {@link CassandraTypeHandler}. - * - * @param colName - which is used to fetch Key from valueJSON. - * @param valuesJson - contains all the key value for current incoming stream. - * @return a {@link Boolean} object containing the value represented in cassandra type. - */ - public static Boolean handleCassandraBoolType(String colName, JSONObject valuesJson) { - return valuesJson.optBoolean(colName, false); - } - - /** - * Generates a Type based on the provided {@link CassandraTypeHandler}. - * - * @param colName - which is used to fetch Key from valueJSON. - * @param valuesJson - contains all the key value for current incoming stream. - * @return a {@link Float} object containing the value represented in cassandra type. - */ - public static Float handleCassandraFloatType(String colName, JSONObject valuesJson) { - try { - return valuesJson.getBigDecimal(colName).floatValue(); - } catch (JSONException e) { - return null; - } - } - - /** - * Generates a Type based on the provided {@link CassandraTypeHandler}. - * - * @param colName - which is used to fetch Key from valueJSON. - * @param valuesJson - contains all the key value for current incoming stream. - * @return a {@link Double} object containing the value represented in cassandra type. - */ - public static Double handleCassandraDoubleType(String colName, JSONObject valuesJson) { - try { - return valuesJson.getBigDecimal(colName).doubleValue(); - } catch (JSONException e) { - return null; + throw new IllegalArgumentException("Invalid IP address format for: " + inetString, e); } } - /** - * Generates a Type based on the provided {@link CassandraTypeHandler}. - * - * @param colName - which is used to fetch Key from valueJSON. - * @param valuesJson - contains all the key value for current incoming stream. - * @return a {@link ByteBuffer} object containing the value represented in cassandra type. - */ - public static ByteBuffer handleCassandraBlobType(String colName, JSONObject valuesJson) { - Object colValue = valuesJson.opt(colName); - if (colValue == null) { - return null; - } - return parseBlobType(colValue); - } - /** * Generates a Type based on the provided {@link CassandraTypeHandler}. * * @param colValue - contains all the key value for current incoming stream. * @return a {@link ByteBuffer} object containing the value represented in cassandra type. */ - public static ByteBuffer parseBlobType(Object colValue) { + private static ByteBuffer parseBlobType(Object colValue) { byte[] byteArray; + if (colValue instanceof byte[]) { byteArray = (byte[]) colValue; } else if (colValue instanceof String) { @@ -229,25 +172,30 @@ public static ByteBuffer parseBlobType(Object colValue) { } else { throw new IllegalArgumentException("Unsupported type for column"); } + return ByteBuffer.wrap(byteArray); } /** - * Generates a {@link LocalDate} based on the provided {@link CassandraTypeHandler}. - * - *

This method processes the given JSON object to extract a date value using the specified - * column name and formatter. It specifically handles the "Cassandra Date" format (yyyy-MM-dd). - * The resulting {@link LocalDate} represents the date value associated with the column. - * - * @param colName - the key used to fetch the value from the provided {@link JSONObject}. - * @param valuesJson - the JSON object containing all key-value pairs for the current incoming - * data stream. - * @return a {@link LocalDate} object containing the date value represented in Cassandra type - * format. If the column is missing or contains an invalid value, this will return {@code - * null}. + * Converts a hexadecimal string into a byte array. + * + * @param binaryEncodedStr the hexadecimal string to be converted. It must have an even number of + * characters, as each pair of characters represents one byte. + * @return a byte array representing the binary data equivalent of the hexadecimal string. */ - public static LocalDate handleCassandraDateType(String colName, JSONObject valuesJson) { - return handleCassandraGenericDateType(colName, valuesJson, "yyyy-MM-dd"); + private static byte[] convertBinaryEncodedStringToByteArray(String binaryEncodedStr) { + int length = binaryEncodedStr.length(); + int byteCount = (length + 7) / 8; + byte[] byteArray = new byte[byteCount]; + + for (int i = 0; i < byteCount; i++) { + int startIndex = i * 8; + int endIndex = Math.min(startIndex + 8, length); + String byteString = binaryEncodedStr.substring(startIndex, endIndex); + byteArray[i] = (byte) Integer.parseInt(byteString, 2); + } + + return byteArray; } /** @@ -265,710 +213,482 @@ public static LocalDate handleCassandraDateType(String colName, JSONObject value *

This method is particularly useful for processing timestamp data stored in Cassandra, where * timestamps are often stored as ISO-8601 strings. * - * @param colName the key used to fetch the value from the provided {@link JSONObject}. - * @param valuesJson the JSON object containing key-value pairs, including the timestamp value. + * @param timestampValue the used to parse the Instant. * @return an {@link Instant} representing the parsed timestamp value in UTC. * @throws IllegalArgumentException if the column value is missing, empty, or cannot be parsed as * a valid timestamp. */ - public static Instant handleCassandraTimestampType(String colName, JSONObject valuesJson) { - String timestampValue = valuesJson.optString(colName, null); + private static Instant handleCassandraTimestampType(String timestampValue) { if (timestampValue == null || timestampValue.isEmpty()) { throw new IllegalArgumentException( - "Timestamp value for column " + colName + " is null or empty."); + "Timestamp value for " + timestampValue + " is null or empty."); } return convertToCassandraTimestamp(timestampValue); } - /** - * A helper method that handles the conversion of a given column value to a {@link LocalDate} - * based on the specified date format (formatter). - * - *

This method extracts the value for the given column name from the provided JSON object and - * parses it into a {@link LocalDate} based on the provided date format. If the value is in an - * unsupported type or format, an exception is thrown. - * - * @param colName - the key used to fetch the value from the provided {@link JSONObject}. - * @param valuesJson - the JSON object containing all key-value pairs for the current incoming - * data stream. - * @param formatter - the date format pattern used to parse the value (e.g., "yyyy-MM-dd"). - * @return a {@link LocalDate} object containing the parsed date value. If the column is missing - * or invalid, this method returns {@code null}. - */ - public static LocalDate handleCassandraGenericDateType( - String colName, JSONObject valuesJson, String formatter) { - Object colValue = valuesJson.opt(colName); - if (colValue == null) { - return null; - } - - if (formatter == null) { - formatter = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; - } - - return parseDate(colName, colValue, formatter); - } - - /** - * Parses a column value (String, {@link java.util.Date}, or {@code Long}) into a {@link - * LocalDate} using the specified date format. - * - *

This method handles different data types (String, Date, Long) by converting them into a - * {@link LocalDate}. The provided formatter is used to parse date strings, while other types are - * converted based on their corresponding representations. - * - * @param colName - the key used to fetch the value from the provided {@link JSONObject}. - * @param colValue - the value to be parsed into a {@link LocalDate}. - * @param formatter - the date format pattern used to parse date strings. - * @return a {@link LocalDate} object parsed from the given value. - * @throws IllegalArgumentException if the value cannot be parsed or is of an unsupported type. - */ - public static LocalDate parseDate(String colName, Object colValue, String formatter) { - LocalDate localDate; - if (colValue instanceof String) { - try { - DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(formatter); - localDate = LocalDate.parse((String) colValue, dateFormatter); - } catch (DateTimeParseException e) { - throw new IllegalArgumentException("Invalid date format for column " + colName, e); - } - } else if (colValue instanceof java.util.Date) { - localDate = - ((java.util.Date) colValue) - .toInstant() - .atZone(java.time.ZoneId.systemDefault()) - .toLocalDate(); - } else if (colValue instanceof Long) { - localDate = - java.time.Instant.ofEpochMilli((Long) colValue) - .atZone(java.time.ZoneId.systemDefault()) - .toLocalDate(); - } else { - throw new IllegalArgumentException("Unsupported type for column " + colName); - } - return localDate; - } - /** * Generates a Type based on the provided {@link CassandraTypeHandler}. * - * @param colName - which is used to fetch Key from valueJSON. - * @param valuesJson - contains all the key value for current incoming stream. - * @return a {@link String} object containing String as value represented in cassandra type. - */ - public static String handleCassandraTextType(String colName, JSONObject valuesJson) { - return valuesJson.optString( - colName, null); // Get the value or null if the key is not found or the value is null - } - - /** - * Generates a Type based on the provided {@link CassandraTypeHandler}. - * - * @param colName - which is used to fetch Key from valueJSON. - * @param valuesJson - contains all the key value for current incoming stream. + * @param uuidString - which is used to parsed and return UUID. * @return a {@link UUID} object containing UUID as value represented in cassandra type. */ - public static UUID handleCassandraUuidType(String colName, JSONObject valuesJson) { - String uuidString = - valuesJson.optString( - colName, null); // Get the value or null if the key is not found or the value is null - + private static UUID handleCassandraUuidType(String uuidString) { if (uuidString == null) { return null; } - return UUID.fromString(uuidString); } - /** - * Generates a Type based on the provided {@link CassandraTypeHandler}. - * - * @param colName - which is used to fetch Key from valueJSON. - * @param valuesJson - contains all the key value for current incoming stream. - * @return a {@link Long} object containing Long as value represented in cassandra type. - */ - public static Long handleCassandraBigintType(String colName, JSONObject valuesJson) { - try { - return valuesJson.getBigInteger(colName).longValue(); - } catch (JSONException e) { - return null; + private static Instant convertToCassandraTimestamp(String timestampValue) { + if (timestampValue == null || timestampValue.trim().isEmpty()) { + throw new IllegalArgumentException("Timestamp value cannot be null or empty"); } - } - /** - * Generates a Type based on the provided {@link CassandraTypeHandler}. - * - * @param colName - which is used to fetch Key from valueJSON. - * @param valuesJson - contains all the key value for current incoming stream. - * @return a {@link Integer} object containing Integer as value represented in cassandra type. - */ - public static Integer handleCassandraIntType(String colName, JSONObject valuesJson) { - try { - return valuesJson.getBigInteger(colName).intValue(); - } catch (JSONException e) { - return null; - } - } + List formatters = + Arrays.asList( + DateTimeFormatter.ISO_INSTANT, + DateTimeFormatter.ISO_DATE_TIME, + DateTimeFormatter.ISO_LOCAL_DATE, + DateTimeFormatter.ISO_TIME, + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"), + DateTimeFormatter.ofPattern("MM/dd/yyyy"), + DateTimeFormatter.ofPattern("yyyy/MM/dd"), + DateTimeFormatter.ofPattern("dd-MM-yyyy"), + DateTimeFormatter.ofPattern("dd/MM/yyyy"), + DateTimeFormatter.ofPattern("MM-dd-yyyy"), + DateTimeFormatter.ofPattern("dd MMM yyyy")); + + for (DateTimeFormatter formatter : formatters) { + try { + TemporalAccessor temporal = formatter.parse(timestampValue); - /** - * Generates a {@link List} object containing a list of long values from Cassandra. - * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link List} object containing a list of long values represented in Cassandra. - */ - public static List handleInt64ArrayType(String colName, JSONObject valuesJson) { - return handleArrayType( - colName, - valuesJson, - obj -> { - if (obj instanceof Long) { - return (Long) obj; - } else if (obj instanceof Number) { - return ((Number) obj).longValue(); - } else if (obj instanceof String) { - try { - return Long.getLong((String) obj); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Invalid number format for column " + colName, e); - } - } else { - throw new IllegalArgumentException("Unsupported type for column " + colName); - } - }); - } + if (temporal.isSupported(ChronoField.INSTANT_SECONDS)) { + return Instant.from(temporal); + } - /** - * Generates a {@link Set} object containing a set of long values from Cassandra. - * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link Set} object containing a set of long values represented in Cassandra. - */ - public static Set handleInt64SetType(String colName, JSONObject valuesJson) { - return new HashSet<>(handleInt64ArrayType(colName, valuesJson)); - } + if (temporal.isSupported(ChronoField.EPOCH_DAY)) { + return LocalDate.from(temporal).atStartOfDay(ZoneOffset.UTC).toInstant(); + } - /** - * Generates a {@link List} object containing a list of integer values from Cassandra by - * converting long values to int. - * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link List} object containing a list of integer values represented in Cassandra. - */ - public static List handleInt64ArrayAsInt32Array(String colName, JSONObject valuesJson) { - return handleInt64ArrayType(colName, valuesJson).stream() - .map(Long::intValue) - .collect(Collectors.toList()); - } + if (temporal.isSupported(ChronoField.SECOND_OF_DAY)) { + return LocalTime.from(temporal) + .atDate(LocalDate.now(ZoneOffset.UTC)) + .atZone(ZoneOffset.UTC) + .toInstant(); + } + } catch (DateTimeParseException ex) { + LOG.debug("Formatter failed: {}, Exception: {}", formatter, ex.getMessage()); + } + } - /** - * Generates a {@link Set} object containing a set of integer values from Cassandra by converting - * long values to int. - * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link Set} object containing a set of integer values represented in Cassandra. - */ - public static Set handleInt64ArrayAsInt32Set(String colName, JSONObject valuesJson) { - return handleInt64ArrayType(colName, valuesJson).stream() - .map(Long::intValue) - .collect(Collectors.toSet()); + throw new IllegalArgumentException("Failed to parse timestamp value: " + timestampValue); } /** - * Generates a {@link Set} object containing a set of string values from Cassandra. + * Safely executes a handler method, catching exceptions and rethrowing them as + * IllegalArgumentException exceptions. * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link Set} object containing a set of string values represented in Cassandra. - */ - public static Set handleStringSetType(String colName, JSONObject valuesJson) { - return new HashSet<>(handleStringArrayType(colName, valuesJson)); - } - - /** - * Generates a {@link List} object containing a list of string values from Cassandra. + *

This method provides exception safety by wrapping the execution of a supplier function. * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link List} object containing a list of string values represented in Cassandra. + * @param The return type of the handler. + * @param supplier A functional interface providing the value. + * @return The result of the supplier function. + * @throws IllegalArgumentException If an exception occurs during the supplier execution. */ - public static List handleStringArrayType(String colName, JSONObject valuesJson) { - return handleArrayType(colName, valuesJson, String::valueOf); + private static T safeHandle(HandlerSupplier supplier) { + try { + return supplier.get(); + } catch (Exception e) { + LOG.error(e.getMessage()); + throw new IllegalArgumentException("Error handling type: " + e.getMessage(), e); + } } /** - * Generates a {@link List} object containing a list of boolean values from Cassandra. + * Handles the conversion of a Spanner column type to an appropriate value. * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link List} object containing a list of boolean values represented in Cassandra. - */ - public static List handleBoolArrayType(String colName, JSONObject valuesJson) { - return handleArrayType( - colName, valuesJson, obj -> obj instanceof String && Boolean.parseBoolean((String) obj)); - } - - /** - * Generates a {@link Set} object containing a set of boolean values from Cassandra. + *

This method attempts to retrieve the value for the specified column from the provided JSON + * object and return it as a string. If the value is not found or an error occurs, it handles the + * exception and returns null or throws an exception accordingly. * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link Set} object containing a set of boolean values represented in Cassandra. + * @param spannerType The type of the Spanner column (currently unused in the method, but might be + * used for further expansion). + * @param columnName The name of the column whose value is to be retrieved. + * @param valuesJson The JSON object containing the values of the columns. + * @return The value of the column as a string, or null if the value is not found. + * @throws IllegalArgumentException If an error occurs during the processing of the value. */ - public static Set handleBoolSetTypeString(String colName, JSONObject valuesJson) { - return new HashSet<>(handleBoolArrayType(colName, valuesJson)); + private static Object handleSpannerColumnType( + String spannerType, String columnName, JSONObject valuesJson) { + try { + if (spannerType.contains("string")) { + return valuesJson.optString(columnName); + } else if (spannerType.contains("bytes")) { + if (valuesJson.isNull(columnName)) { + return null; + } + String hexEncodedString = valuesJson.optString(columnName); + return convertBinaryEncodedStringToByteArray(hexEncodedString); + } else { + return valuesJson.isNull(columnName) ? null : valuesJson.opt(columnName); + } + } catch (Exception e) { + throw new IllegalArgumentException( + "Exception Caught During parsing for Spanner column type: " + spannerType); + } } /** - * Generates a {@link List} object containing a list of double values from Cassandra. - * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link List} object containing a list of double values represented in Cassandra. - */ - public static List handleFloat64ArrayType(String colName, JSONObject valuesJson) { - return handleArrayType( - colName, - valuesJson, - obj -> { - if (obj instanceof Number) { - return ((Number) obj).doubleValue(); - } else if (obj instanceof String) { - try { - return Double.valueOf((String) obj); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Invalid number format for column " + colName, e); - } - } else { - throw new IllegalArgumentException("Unsupported type for column " + colName); - } - }); - } + * Parses a column value based on its Cassandra column type and wraps it into {@link + * PreparedStatementValueObject}. + * + *

This method processes basic Cassandra types (e.g., text, bigint, boolean, timestamp) and + * special types such as {@link Instant}, {@link UUID}, {@link BigInteger}, and {@link Duration}. + * + * @param columnType The Cassandra column type (e.g., "text", "timestamp"). + * @param colValue The column value to parse and wrap. + * @return A {@link PreparedStatementValueObject} containing the parsed column value. + * @throws IllegalArgumentException If the column value cannot be converted to the specified type. + */ + private static PreparedStatementValueObject parseAndCastToCassandraType( + String columnType, Object colValue) { + + // Handle collection types + if (columnType.startsWith("list<")) { + return safeHandle( + () -> { + JSONArray parsedJSONArray = + colValue instanceof JSONArray + ? (JSONArray) colValue + : new JSONArray((String) colValue); + return PreparedStatementValueObject.create( + columnType, parseCassandraList(columnType, parsedJSONArray)); + }); + } else if (columnType.startsWith("set<")) { + return safeHandle( + () -> { + JSONArray parsedJSONArray = + colValue instanceof JSONArray + ? (JSONArray) colValue + : new JSONArray((String) colValue); + return PreparedStatementValueObject.create( + columnType, parseCassandraSet(columnType, parsedJSONArray)); + }); + } else if (columnType.startsWith("map<")) { + return safeHandle( + () -> { + JSONObject parsedJSON = + colValue instanceof JSONObject + ? (JSONObject) colValue + : new JSONObject((String) colValue); + return PreparedStatementValueObject.create( + columnType, parseCassandraMap(columnType, parsedJSON)); + }); + } - /** - * Generates a {@link Set} object containing a set of double values from Cassandra. - * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link Set} object containing a set of double values represented in Cassandra. - */ - public static Set handleFloat64SetType(String colName, JSONObject valuesJson) { - return new HashSet<>(handleFloat64ArrayType(colName, valuesJson)); + // Handle primitive and standard types + switch (columnType) { + case "ascii": + case "text": + case "varchar": + return PreparedStatementValueObject.create(columnType, (String) colValue); + + case "bigint": + case "int": + case "smallint": + case "tinyint": + return safeHandle( + () -> + PreparedStatementValueObject.create( + columnType, parseNumericType(columnType, colValue.toString()))); + + case "boolean": + return PreparedStatementValueObject.create( + columnType, safeHandle(() -> parseBoolean(colValue.toString()))); + + case "decimal": + return PreparedStatementValueObject.create( + columnType, safeHandle(() -> parseDecimal(colValue.toString()))); + + case "double": + case "float": + return PreparedStatementValueObject.create( + columnType, safeHandle(() -> parseFloatingPoint(columnType, colValue.toString()))); + + case "inet": + return PreparedStatementValueObject.create( + columnType, safeHandle(() -> handleCassandraInetAddressType(colValue.toString()))); + + case "time": + return PreparedStatementValueObject.create( + columnType, + safeHandle( + () -> + handleCassandraTimestampType(colValue.toString()) + .atZone(ZoneId.systemDefault()) + .toLocalTime())); + case "timestamp": + case "datetime": + return PreparedStatementValueObject.create( + columnType, safeHandle(() -> handleCassandraTimestampType(colValue.toString()))); + + case "date": + return PreparedStatementValueObject.create( + columnType, safeHandle(() -> parseDate(colValue.toString()))); + + case "timeuuid": + case "uuid": + return PreparedStatementValueObject.create( + columnType, safeHandle(() -> handleCassandraUuidType(colValue.toString()))); + + case "varint": + return PreparedStatementValueObject.create( + columnType, safeHandle(() -> handleCassandraVarintType(colValue.toString()))); + + case "duration": + return PreparedStatementValueObject.create( + columnType, safeHandle(() -> handleCassandraDurationType(colValue.toString()))); + + case "blob": + return safeHandle( + () -> PreparedStatementValueObject.create(columnType, parseBlobType(colValue))); + + default: + return PreparedStatementValueObject.create(columnType, colValue); + } } /** - * Generates a {@link List} object containing a list of float values from Cassandra. - * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link List} object containing a list of float values represented in Cassandra. - */ - public static List handleFloatArrayType(String colName, JSONObject valuesJson) { - return handleFloat64ArrayType(colName, valuesJson).stream() - .map(Double::floatValue) - .collect(Collectors.toList()); + * Parses a numeric value to the corresponding type based on the given column type. + * + * @param columnType the type of the column (e.g., "bigint", "int", "smallint", "tinyint"). + * @param colValue the value to parse, either as a {@code String} or a {@code Number}. + * @return the parsed numeric value as the appropriate type (e.g., {@code Long}, {@code Integer}, + * {@code Short}, {@code Byte}). + * @throws IllegalArgumentException if the {@code colValue} type is unsupported or does not match + * the column type. + */ + private static Object parseNumericType(String columnType, Object colValue) { + return safeHandle( + () -> { + switch (columnType) { + case "bigint": + return Long.parseLong((String) colValue); + case "int": + return Integer.parseInt((String) colValue); + case "smallint": + return Short.parseShort((String) colValue); + case "tinyint": + return Byte.parseByte((String) colValue); + } + throw new IllegalArgumentException( + "Unsupported type for " + columnType + ": " + colValue.getClass()); + }); } /** - * Generates a {@link Set} object containing a set of float values from Cassandra. + * Parses a boolean value from the provided input. * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link Set} object containing a set of float values represented in Cassandra. + * @param colValue the value to parse, either as a {@code String} or a {@code Boolean}. + * @return the parsed boolean value. + * @throws ClassCastException if the {@code colValue} is not a {@code String} or {@code Boolean}. */ - public static Set handleFloatSetType(String colName, JSONObject valuesJson) { - return handleFloat64SetType(colName, valuesJson).stream() - .map(Double::floatValue) - .collect(Collectors.toSet()); + private static Boolean parseBoolean(Object colValue) { + if (Arrays.asList("0", "1").contains((String) colValue)) { + return colValue.equals("1"); + } + return BooleanUtils.toBoolean((String) colValue); } /** - * Generates a {@link List} object containing a list of LocalDate values from Cassandra. + * Parses a decimal value from the provided input. * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link List} object containing a list of LocalDate values represented in Cassandra. + * @param colValue the value to parse, either as a {@code String} or a {@code Number}. + * @return the parsed decimal value as a {@code BigDecimal}. + * @throws NumberFormatException if the {@code colValue} is a {@code String} and cannot be + * converted to {@code BigDecimal}. + * @throws ClassCastException if the {@code colValue} is not a {@code String}, {@code Number}, or + * {@code BigDecimal}. */ - public static List handleDateArrayType(String colName, JSONObject valuesJson) { - return handleArrayType( - colName, valuesJson, obj -> LocalDate.parse(obj.toString(), DateTimeFormatter.ISO_DATE)); + private static BigDecimal parseDecimal(Object colValue) { + return new BigDecimal((String) colValue); } /** - * Generates a {@link Set} object containing a set of LocalDate values from Cassandra. + * Parses a floating-point value to the corresponding type based on the given column type. * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link Set} object containing a set of LocalDate values represented in Cassandra. + * @param columnType the type of the column (e.g., "double", "float"). + * @param colValue the value to parse, either as a {@code String} or a {@code Number}. + * @return the parsed floating-point value as a {@code Double} or {@code Float}. + * @throws IllegalArgumentException if the column type is invalid or the value cannot be parsed. */ - public static Set handleDateSetType(String colName, JSONObject valuesJson) { - return new HashSet<>(handleDateArrayType(colName, valuesJson)); + private static Object parseFloatingPoint(String columnType, Object colValue) { + return columnType.equals("double") + ? Double.parseDouble((String) colValue) + : Float.parseFloat((String) colValue); } - /** - * Generates a {@link List} object containing a list of Timestamp values from Cassandra. - * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link List} object containing a list of Timestamp values represented in Cassandra. - */ - public static List handleTimestampArrayType(String colName, JSONObject valuesJson) { - return handleArrayType( - colName, - valuesJson, - value -> - Timestamp.valueOf( - parseDate(colName, value, "yyyy-MM-dd'T'HH:mm:ss.SSSX").atStartOfDay())); + private static LocalDate parseDate(Object colValue) { + return handleCassandraTimestampType((String) colValue) + .atZone(ZoneId.systemDefault()) + .toLocalDate(); } /** - * Generates a {@link Set} object containing a set of Timestamp values from Cassandra. + * Parses a Cassandra list from the given JSON array. * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing key-value pairs for the current incoming - * stream. - * @return a {@link Set} object containing a set of Timestamp values represented in Cassandra. + * @param columnType the Cassandra column type (e.g., "list of int", "list of text") + * @param colValue the JSON array representing the list values + * @return a {@link List} containing parsed values, or an empty list if {@code colValue} is null */ - public static Set handleTimestampSetType(String colName, JSONObject valuesJson) { - return new HashSet<>(handleTimestampArrayType(colName, valuesJson)); + private static List parseCassandraList(String columnType, JSONArray colValue) { + if (colValue == null) { + return Collections.emptyList(); + } + String innerType = extractInnerType(columnType); + List parsedList = new ArrayList<>(); + for (int i = 0; i < colValue.length(); i++) { + Object value = colValue.get(i); + parsedList.add(parseNestedType(innerType, value).value()); + } + return parsedList; } /** - * Generates a Type based on the provided {@link CassandraTypeHandler}. + * Extracts the inner type of a Cassandra collection column (e.g., "list of int" -> "int"). * - * @param colName - which is used to fetch Key from valueJSON. - * @param valuesJson - contains all the key value for current incoming stream. - * @return a {@link List} object containing List of ByteBuffer as value represented in cassandra - * type. + * @param columnType the Cassandra column type + * @return the extracted inner type as a {@link String} */ - public static List handleByteArrayType(String colName, JSONObject valuesJson) { - return handleArrayType(colName, valuesJson, CassandraTypeHandler::parseBlobType); + private static String extractInnerType(String columnType) { + return columnType.substring(columnType.indexOf('<') + 1, columnType.lastIndexOf('>')); } /** - * Generates a Type based on the provided {@link CassandraTypeHandler}. + * Extracts the key and value types from a Cassandra map column type (e.g., "map of int and + * text"). * - * @param colName - which is used to fetch Key from valueJSON. - * @param valuesJson - contains all the key value for current incoming stream. - * @return a {@link List} object containing List of Type T as value represented in cassandra type - * which will be assigned runtime. + * @param columnType the Cassandra column type + * @return an array of two {@link String}s, where the first element is the key type and the second + * element is the value type */ - public static List handleArrayType( - String colName, JSONObject valuesJson, TypeParser parser) { - return valuesJson.getJSONArray(colName).toList().stream() - .map(parser::parse) - .collect(Collectors.toList()); + private static String[] extractKeyValueTypes(String columnType) { + String innerTypes = + columnType.substring(columnType.indexOf('<') + 1, columnType.lastIndexOf('>')); + return innerTypes.split(",", 2); } /** - * Generates a Type based on the provided {@link CassandraTypeHandler}. + * Parses a nested Cassandra type from a given value. * - * @param colName - which is used to fetch Key from valueJSON. - * @param valuesJson - contains all the key value for current incoming stream. - * @return a {@link Set} object containing Set of ByteBuffer as value represented in cassandra - * type. + * @param type the Cassandra column type (e.g., "int", "text", "map of int of text") + * @param value the value to parse + * @return a {@link PreparedStatementValueObject} representing the parsed type */ - public static Set handleByteSetType(String colName, JSONObject valuesJson) { - return new HashSet<>(handleByteArrayType(colName, valuesJson)); + private static PreparedStatementValueObject parseNestedType(String type, Object value) { + return parseAndCastToCassandraType(type.trim(), value); } /** - * Converts a stringified JSON object to a {@link Map} representation for Cassandra. - * - *

This method fetches the value associated with the given column name ({@code colName}) from - * the {@code valuesJson} object, parses the stringified JSON, and returns it as a {@link Map}. + * Parses a Cassandra set from the given JSON array. * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing all the key-value pairs for the current - * incoming stream. - * @return A {@link Map} representing the parsed JSON from the stringified JSON. - * @throws IllegalArgumentException If the value is not a valid stringified JSON or cannot be - * parsed. + * @param columnType the Cassandra column type (e.g., "set of int", "set of text") + * @param colValue the JSON array representing the set values + * @return a {@link Set} containing parsed values, or an empty set if {@code colValue} is null */ - public static Map handleStringifiedJsonToMap( - String colName, JSONObject valuesJson) { - Object value = valuesJson.get(colName); - if (value instanceof String) { - String jsonString = (String) value; - try { - JSONObject jsonObject = new JSONObject(jsonString); - Map map = new HashMap<>(); - for (String key : jsonObject.keySet()) { - Object jsonValue = jsonObject.get(key); - if (jsonValue instanceof JSONArray) { - map.put(key, jsonObject.getJSONArray(key)); - } else if (jsonValue instanceof JSONObject) { - map.put(key, jsonObject.getJSONObject(key)); - } else { - map.put(key, jsonValue); - } - } - return map; - } catch (Exception e) { - throw new IllegalArgumentException( - "Invalid stringified JSON format for column: " + colName, e); - } - } else { - throw new IllegalArgumentException( - "Invalid format for column: " + colName + ". Expected a stringified JSON."); + private static Set parseCassandraSet(String columnType, JSONArray colValue) { + if (colValue == null) { + return Collections.emptySet(); } - } - - /** - * Converts a stringified JSON array to a {@link List} representation for Cassandra. - * - *

This method fetches the value associated with the given column name ({@code colName}) from - * the {@code valuesJson} object, parses the stringified JSON array, and returns it as a {@link - * List}. - * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing all the key-value pairs for the current - * incoming stream. - * @return A {@link List} representing the parsed JSON array from the stringified JSON. - * @throws IllegalArgumentException If the value is not a valid stringified JSON array or cannot - * be parsed. - */ - public static List handleStringifiedJsonToList(String colName, JSONObject valuesJson) { - Object value = valuesJson.get(colName); - if (value instanceof String) { - String jsonString = (String) value; - try { - JSONArray jsonArray = new JSONArray(jsonString); - List list = new ArrayList<>(); - for (int i = 0; i < jsonArray.length(); i++) { - list.add(jsonArray.get(i)); - } - return list; - } catch (Exception e) { - throw new IllegalArgumentException( - "Invalid stringified JSON array format for column: " + colName, e); - } - } else { - throw new IllegalArgumentException( - "Invalid format for column: " + colName + ". Expected a stringified JSON array."); + String innerType = extractInnerType(columnType); + Set parsedSet = new HashSet<>(); + for (int i = 0; i < colValue.length(); i++) { + Object value = colValue.get(i); + parsedSet.add(parseNestedType(innerType, value).value()); } + return parsedSet; } /** - * Converts a stringified JSON array to a {@link Set} representation for Cassandra. - * - *

This method fetches the value associated with the given column name ({@code colName}) from - * the {@code valuesJson} object, parses the stringified JSON array, and returns it as a {@link - * Set}. - * - * @param colName - The column name used to fetch the key from {@code valuesJson}. - * @param valuesJson - The {@link JSONObject} containing all the key-value pairs for the current - * incoming stream. - * @return A {@link Set} representing the parsed JSON array from the stringified JSON. - * @throws IllegalArgumentException If the value is not a valid stringified JSON array or cannot - * be parsed. - */ - public static Set handleStringifiedJsonToSet(String colName, JSONObject valuesJson) { - return new HashSet<>(handleStringifiedJsonToList(colName, valuesJson)); - } - - /** - * Converts an {@link Integer} to a {@code short} (SmallInt). - * - *

This method checks if the {@code integerValue} is within the valid range for a {@code - * smallint} (i.e., between {@link Short#MIN_VALUE} and {@link Short#MAX_VALUE}). If the value is - * out of range, it throws an {@link IllegalArgumentException}. + * Parses a Cassandra map from the given JSON object. * - * @param integerValue The integer value to be converted. - * @return The converted {@code short} value. - * @throws IllegalArgumentException If the {@code integerValue} is out of range for a {@code - * smallint}. + * @param columnType the Cassandra column type (e.g., "map of int and text") + * @param colValue the JSON object representing the map values + * @return a {@link Map} containing parsed key-value pairs, or an empty map if {@code colValue} is + * null */ - public static short convertToSmallInt(Integer integerValue) { - if (integerValue < Short.MIN_VALUE || integerValue > Short.MAX_VALUE) { - throw new IllegalArgumentException("Value is out of range for smallint."); + private static Map parseCassandraMap(String columnType, JSONObject colValue) { + if (colValue == null) { + return Collections.emptyMap(); } - return integerValue.shortValue(); - } - - /** - * Converts an {@link Integer} to a {@code byte} (TinyInt). - * - *

This method checks if the {@code integerValue} is within the valid range for a {@code - * tinyint} (i.e., between {@link Byte#MIN_VALUE} and {@link Byte#MAX_VALUE}). If the value is out - * of range, it throws an {@link IllegalArgumentException}. - * - * @param integerValue The integer value to be converted. - * @return The converted {@code byte} value. - * @throws IllegalArgumentException If the {@code integerValue} is out of range for a {@code - * tinyint}. - */ - public static byte convertToTinyInt(Integer integerValue) { - if (integerValue < Byte.MIN_VALUE || integerValue > Byte.MAX_VALUE) { - throw new IllegalArgumentException("Value is out of range for tinyint."); + String[] keyValueTypes = extractKeyValueTypes(columnType); + String keyType = keyValueTypes[0]; + String valueType = keyValueTypes[1]; + + Map parsedMap = new HashMap<>(); + for (String key : colValue.keySet()) { + Object parsedKey = parseNestedType(keyType, key).value(); + Object parsedValue = parseNestedType(valueType, colValue.get(key)).value(); + parsedMap.put(parsedKey, parsedValue); } - return integerValue.byteValue(); + return parsedMap; } /** - * Escapes single quotes in a Cassandra string by replacing them with double single quotes. + * Parses a column's value from a JSON object based on Spanner and source database column types. * - *

This method is commonly used to sanitize strings before inserting them into Cassandra - * queries, where single quotes need to be escaped by doubling them (i.e., `'` becomes `''`). + *

This method determines the column type, extracts the value using helper methods, and returns + * a {@link PreparedStatementValueObject} containing the column value formatted for Cassandra. * - * @param value The string to be escaped. - * @return The escaped string where single quotes are replaced with double single quotes. + * @param spannerColDef The Spanner column definition containing column name and type. + * @param sourceColDef The source database column definition containing column type. + * @param valuesJson The JSON object containing column values. + * @param sourceDbTimezoneOffset The timezone offset for date-time columns (if applicable). + * @return A {@link PreparedStatementValueObject} containing the parsed column value. */ - public static String escapeCassandraString(String value) { - return value.replace("'", "''"); - } + public static PreparedStatementValueObject getColumnValueByType( + SpannerColumnDefinition spannerColDef, + SourceColumnDefinition sourceColDef, + JSONObject valuesJson, + String sourceDbTimezoneOffset) { - /** - * Converts a string representation of a timestamp to a Cassandra-compatible timestamp. - * - *

The method parses the {@code value} as a {@link ZonedDateTime}, applies the given timezone - * offset to adjust the time, and converts the result into a UTC timestamp string that is - * compatible with Cassandra. - * - * @param value The timestamp string in ISO-8601 format (e.g., "2024-12-05T10:15:30+01:00"). - * @param timezoneOffset The timezone offset (e.g., "+02:00") to apply to the timestamp. - * @return A string representation of the timestamp in UTC that is compatible with Cassandra. - * @throws RuntimeException If the timestamp string is invalid or the conversion fails. - */ - public static String convertToCassandraTimestamp(String value, String timezoneOffset) { - try { - ZonedDateTime dateTime = ZonedDateTime.parse(value); - ZoneOffset offset = ZoneOffset.of(timezoneOffset); - dateTime = dateTime.withZoneSameInstant(offset); - return "'" + dateTime.withZoneSameInstant(ZoneOffset.UTC).toString() + "'"; - } catch (DateTimeParseException e) { - throw new RuntimeException(e); + if (spannerColDef == null || sourceColDef == null) { + throw new IllegalArgumentException("Column definitions cannot be null."); } - } - /** - * Converts a string representation of a date to a {@link LocalDate} compatible with Cassandra. - * - *

The method parses the {@code dateString} into an {@link Instant}, converts it to a {@link - * Date}, and then retrieves the corresponding {@link LocalDate} from the system's default time - * zone. - * - * @param dateString The date string in ISO-8601 format (e.g., "2024-12-05T00:00:00Z"). - * @return The {@link LocalDate} representation of the date. - */ - public static LocalDate convertToCassandraDate(String dateString) { - Instant instant = convertToCassandraTimestamp(dateString); - ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault()); - return zonedDateTime.toLocalDate(); - } + String spannerType = spannerColDef.getType().getName().toLowerCase(); + String cassandraType = sourceColDef.getType().getName().toLowerCase(); + String columnName = spannerColDef.getName(); - /** - * Converts a string representation of a timestamp to an {@link Instant} compatible with - * Cassandra. - * - *

The method parses the {@code dateString} into an {@link Instant}, which represents an - * instantaneous point in time and is compatible with Cassandra timestamp types. - * - * @param timestampValue The timestamp string in ISO-8601 format (e.g., "2024-12-05T10:15:30Z"). - * @return The {@link Instant} representation of the timestamp. - */ - public static Instant convertToCassandraTimestamp(String timestampValue) { - try { - return Instant.parse(timestampValue); - } catch (DateTimeParseException e) { - try { - return ZonedDateTime.parse(timestampValue) - .withZoneSameInstant(java.time.ZoneOffset.UTC) - .toInstant(); - } catch (DateTimeParseException nestedException) { - throw new IllegalArgumentException( - "Failed to parse timestamp value" + timestampValue, nestedException); - } - } - } + Object columnValue = handleSpannerColumnType(spannerType, columnName, valuesJson); - /** - * Validates if the given string represents a valid UUID. - * - *

This method attempts to parse the provided string as a UUID using {@link - * UUID#fromString(String)}. If parsing is successful, it returns {@code true}, indicating that - * the string is a valid UUID. Otherwise, it returns {@code false}. - * - * @param value The string to check if it represents a valid UUID. - * @return {@code true} if the string is a valid UUID, {@code false} otherwise. - */ - public static boolean isValidUUID(String value) { - try { - UUID.fromString(value); - return true; - } catch (IllegalArgumentException e) { - return false; - } - } - - /** - * Validates if the given string represents a valid IP address. - * - *

This method attempts to resolve the provided string as an {@link InetAddresses} using {@link - * InetAddresses#forString(String)}. If successful, it returns {@code true}, indicating that the - * string is a valid IP address. Otherwise, it returns {@code false}. - * - * @param value The string to check if it represents a valid IP address. - * @return {@code true} if the string is a valid IP address, {@code false} otherwise. - */ - public static boolean isValidIPAddress(String value) { - try { - InetAddresses.forString(value); - return true; - } catch (Exception e) { - return false; + if (columnValue == null) { + LOG.warn("Column value is null for column: {}, type: {}", columnName, spannerType); + return PreparedStatementValueObject.create(cassandraType, NullClass.INSTANCE); } + return PreparedStatementValueObject.create(cassandraType, columnValue); } /** - * Validates if the given string is a valid JSON object. + * Casts the given column value to the expected type based on the Cassandra column type. * - *

This method attempts to parse the string using {@link JSONObject} to check if the value - * represents a valid JSON object. If the string is valid JSON, it returns {@code true}, otherwise - * {@code false}. + *

This method attempts to parse and cast the column value to a type compatible with the + * provided Cassandra column type using {@code parseAndGenerateCassandraType}. If the value cannot + * be cast correctly, an error is logged, and an exception is thrown. * - * @param value The string to check if it represents a valid JSON object. - * @return {@code true} if the string is a valid JSON object, {@code false} otherwise. + * @param cassandraType the Cassandra data type of the column (e.g., "text", "bigint", "list of + * text") + * @param columnValue the value of the column to be cast + * @return the column value cast to the expected type + * @throws IllegalArgumentException if the Cassandra type is unsupported or the value is invalid */ - public static boolean isValidJSON(String value) { + public static Object castToExpectedType(String cassandraType, Object columnValue) { try { - new JSONObject(value); - return true; - } catch (Exception e) { - return false; - } - } - - /** - * Helper method to check if a string contains only ASCII characters (0-127). - * - * @param value - The string to check. - * @return true if the string contains only ASCII characters, false otherwise. - */ - public static boolean isAscii(String value) { - for (int i = 0; i < value.length(); i++) { - if (value.charAt(i) > 127) { - return false; - } + return parseAndCastToCassandraType(cassandraType, columnValue).value(); + } catch (IllegalArgumentException e) { + LOG.error("Error converting value for column: {}, type: {}", cassandraType, e.getMessage()); + throw new IllegalArgumentException( + "Error converting value for cassandraType: " + cassandraType); } - return true; } } diff --git a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/processor/InputRecordProcessor.java b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/processor/InputRecordProcessor.java index 9bdfe2bcda..6ea5047c6a 100644 --- a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/processor/InputRecordProcessor.java +++ b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/processor/InputRecordProcessor.java @@ -15,6 +15,8 @@ */ package com.google.cloud.teleport.v2.templates.dbutils.processor; +import static com.google.cloud.teleport.v2.templates.constants.Constants.SOURCE_CASSANDRA; + import com.google.cloud.teleport.v2.spanner.exceptions.InvalidTransformationException; import com.google.cloud.teleport.v2.spanner.migrations.convertors.ChangeEventToMapConvertor; import com.google.cloud.teleport.v2.spanner.migrations.schema.Schema; @@ -53,7 +55,8 @@ public static boolean processRecord( String shardId, String sourceDbTimezoneOffset, IDMLGenerator dmlGenerator, - ISpannerMigrationTransformer spannerToSourceTransformer) + ISpannerMigrationTransformer spannerToSourceTransformer, + String source) throws Exception { try { @@ -95,6 +98,7 @@ public static boolean processRecord( modType, tableName, newValuesJson, keysJson, sourceDbTimezoneOffset) .setSchema(schema) .setCustomTransformationResponse(customTransformationResponse) + .setCommitTimestamp(spannerRecord.getCommitTimestamp()) .build(); DMLGeneratorResponse dmlGeneratorResponse = dmlGenerator.getDMLStatement(dmlGeneratorRequest); @@ -102,7 +106,24 @@ public static boolean processRecord( LOG.warn("DML statement is empty for table: " + tableName); return false; } - dao.write(dmlGeneratorResponse.getDmlStatement()); + // TODO we need to handle it as proper Interface Level as of now we have handle Prepared + // TODO Statement and Raw Statement Differently + /* + * TODO: + * Note: The `SOURCE_CASSANDRA` case not covered in the unit tests. + * Answer: Currently, we have implemented unit tests for the Input Record Processor under the SourceWrittenFn. + * These tests cover the majority of scenarios, but they are tightly coupled with the existing code. + * Adding unit tests for SOURCE_CASSANDRA would require a significant refactoring of the entire unit test file. + * Given the current implementation, such refactoring is deemed unnecessary as it would not provide substantial value or impact. + */ + switch (source) { + case SOURCE_CASSANDRA: + dao.write(dmlGeneratorResponse); + break; + default: + dao.write(dmlGeneratorResponse.getDmlStatement()); + break; + } Counter numRecProcessedMetric = Metrics.counter(shardId, "records_written_to_source_" + shardId); diff --git a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/processor/SourceProcessorFactory.java b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/processor/SourceProcessorFactory.java index 54d70d33c1..5d68c5a256 100644 --- a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/processor/SourceProcessorFactory.java +++ b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/dbutils/processor/SourceProcessorFactory.java @@ -24,12 +24,11 @@ import com.google.cloud.teleport.v2.templates.dbutils.dao.source.CassandraDao; import com.google.cloud.teleport.v2.templates.dbutils.dao.source.IDao; import com.google.cloud.teleport.v2.templates.dbutils.dao.source.JdbcDao; +import com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraDMLGenerator; import com.google.cloud.teleport.v2.templates.dbutils.dml.IDMLGenerator; import com.google.cloud.teleport.v2.templates.dbutils.dml.MySQLDMLGenerator; import com.google.cloud.teleport.v2.templates.exceptions.UnsupportedSourceException; import com.google.cloud.teleport.v2.templates.models.ConnectionHelperRequest; -import com.google.cloud.teleport.v2.templates.models.DMLGeneratorRequest; -import com.google.cloud.teleport.v2.templates.models.DMLGeneratorResponse; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -54,16 +53,7 @@ public class SourceProcessorFactory { static { dmlGeneratorMap.put(Constants.SOURCE_MYSQL, new MySQLDMLGenerator()); - dmlGeneratorMap.put( - Constants.SOURCE_CASSANDRA, - new IDMLGenerator() { - // TODO It will get removed in DML PR added Now for Test case eg: new - // CassandraDMLGenerator() - @Override - public DMLGeneratorResponse getDMLStatement(DMLGeneratorRequest dmlGeneratorRequest) { - return new DMLGeneratorResponse(""); - } - }); + dmlGeneratorMap.put(Constants.SOURCE_CASSANDRA, new CassandraDMLGenerator()); connectionHelperMap.put(Constants.SOURCE_MYSQL, new JdbcConnectionHelper()); connectionHelperMap.put(Constants.SOURCE_CASSANDRA, new CassandraConnectionHelper()); diff --git a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/models/DMLGeneratorRequest.java b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/models/DMLGeneratorRequest.java index 3db153c51e..dcb0693ecf 100644 --- a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/models/DMLGeneratorRequest.java +++ b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/models/DMLGeneratorRequest.java @@ -15,6 +15,7 @@ */ package com.google.cloud.teleport.v2.templates.models; +import com.google.cloud.Timestamp; import com.google.cloud.teleport.v2.spanner.migrations.schema.Schema; import java.util.Map; import org.json.JSONObject; @@ -53,6 +54,7 @@ public class DMLGeneratorRequest { private final String sourceDbTimezoneOffset; private Map customTransformationResponse; + private final Timestamp commitTimestamp; public DMLGeneratorRequest(Builder builder) { this.modType = builder.modType; @@ -62,6 +64,11 @@ public DMLGeneratorRequest(Builder builder) { this.keyValuesJson = builder.keyValuesJson; this.sourceDbTimezoneOffset = builder.sourceDbTimezoneOffset; this.customTransformationResponse = builder.customTransformationResponse; + this.commitTimestamp = builder.commitTimestamp; + } + + public Timestamp getCommitTimestamp() { + return this.commitTimestamp; } public String getModType() { @@ -100,6 +107,7 @@ public static class Builder { private final String sourceDbTimezoneOffset; private Schema schema; private Map customTransformationResponse; + private Timestamp commitTimestamp; public Builder( String modType, @@ -119,6 +127,11 @@ public Builder setSchema(Schema schema) { return this; } + public Builder setCommitTimestamp(Timestamp commitTimestamp) { + this.commitTimestamp = commitTimestamp; + return this; + } + public Builder setCustomTransformationResponse( Map customTransformationResponse) { this.customTransformationResponse = customTransformationResponse; diff --git a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/transforms/SourceWriterFn.java b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/transforms/SourceWriterFn.java index 795284a9d4..bb1a2bc715 100644 --- a/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/transforms/SourceWriterFn.java +++ b/v2/spanner-to-sourcedb/src/main/java/com/google/cloud/teleport/v2/templates/transforms/SourceWriterFn.java @@ -210,7 +210,8 @@ public void processElement(ProcessContext c) { shardId, sourceDbTimezoneOffset, sourceProcessor.getDmlGenerator(), - spannerToSourceTransformer); + spannerToSourceTransformer, + this.source); if (isEventFiltered) { outputWithTag(c, Constants.FILTERED_TAG, Constants.FILTERED_TAG_MESSAGE, spannerRec); } diff --git a/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/dao/source/CassandraDaoTest.java b/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/dao/source/CassandraDaoTest.java index 967dd8b83a..494d207eb7 100644 --- a/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/dao/source/CassandraDaoTest.java +++ b/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/dao/source/CassandraDaoTest.java @@ -27,6 +27,7 @@ import com.datastax.oss.driver.api.core.cql.PreparedStatement; import com.datastax.oss.driver.api.core.cql.Statement; import com.google.cloud.teleport.v2.templates.dbutils.connection.IConnectionHelper; +import com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler; import com.google.cloud.teleport.v2.templates.exceptions.ConnectionException; import com.google.cloud.teleport.v2.templates.models.PreparedStatementGeneratedResponse; import com.google.cloud.teleport.v2.templates.models.PreparedStatementValueObject; @@ -90,6 +91,27 @@ public void testPreparedStatementExecution() throws Exception { verify(mockSession).execute(ArgumentMatchers.eq(mockBoundStatement)); } + @Test + public void testPreparedStatementExecutionForNullAsValue() throws Exception { + String preparedDmlStatement = "INSERT INTO test (id, name) VALUES (?, ?)"; + List> values = + Arrays.asList( + PreparedStatementValueObject.create("date", CassandraTypeHandler.NullClass.INSTANCE), + PreparedStatementValueObject.create("varchar", "text")); + + when(mockPreparedStatementGeneratedResponse.getDmlStatement()).thenReturn(preparedDmlStatement); + when(mockPreparedStatementGeneratedResponse.getValues()).thenReturn(values); + when(mockConnectionHelper.getConnection(anyString())).thenReturn(mockSession); + when(mockSession.prepare(preparedDmlStatement)).thenReturn(mockPreparedStatement); + when(mockPreparedStatement.bind(ArgumentMatchers.any())).thenReturn(mockBoundStatement); + + cassandraDao.write(mockPreparedStatementGeneratedResponse); + + verify(mockSession).prepare(ArgumentMatchers.eq(preparedDmlStatement)); + verify(mockPreparedStatement).bind(ArgumentMatchers.any()); + verify(mockSession).execute(ArgumentMatchers.eq(mockBoundStatement)); + } + @Test public void testWriteWithExceptionInPreparedStatement() throws Exception { String preparedDmlStatement = "INSERT INTO test (id, name) VALUES (?, ?)"; diff --git a/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraDMLGeneratorTest.java b/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraDMLGeneratorTest.java new file mode 100644 index 0000000000..092fe0e00d --- /dev/null +++ b/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraDMLGeneratorTest.java @@ -0,0 +1,925 @@ +/* + * Copyright (C) 2025 Google LLC + * + * Licensed 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 com.google.cloud.teleport.v2.templates.dbutils.dml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import com.google.cloud.Timestamp; +import com.google.cloud.teleport.v2.spanner.migrations.schema.ColumnPK; +import com.google.cloud.teleport.v2.spanner.migrations.schema.NameAndCols; +import com.google.cloud.teleport.v2.spanner.migrations.schema.Schema; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SourceTable; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SpannerColumnDefinition; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SpannerColumnType; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SpannerTable; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SyntheticPKey; +import com.google.cloud.teleport.v2.spanner.migrations.utils.SessionFileReader; +import com.google.cloud.teleport.v2.templates.dbutils.processor.InputRecordProcessor; +import com.google.cloud.teleport.v2.templates.models.DMLGeneratorRequest; +import com.google.cloud.teleport.v2.templates.models.DMLGeneratorResponse; +import com.google.cloud.teleport.v2.templates.models.PreparedStatementGeneratedResponse; +import com.google.cloud.teleport.v2.templates.models.PreparedStatementValueObject; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class CassandraDMLGeneratorTest { + + private CassandraDMLGenerator cassandraDMLGenerator; + + @Before + public void setUp() { + cassandraDMLGenerator = new CassandraDMLGenerator(); + } + + @Test + public void testGetDMLStatement_NullRequest() { + DMLGeneratorResponse response = cassandraDMLGenerator.getDMLStatement(null); + assertNotNull(response); + assertEquals("", response.getDmlStatement()); + } + + @Test + public void testGetDMLStatement_InvalidSchema() { + DMLGeneratorRequest dmlGeneratorRequest = + new DMLGeneratorRequest.Builder("insert", "text", null, null, null).setSchema(null).build(); + + DMLGeneratorResponse response = cassandraDMLGenerator.getDMLStatement(dmlGeneratorRequest); + assertNotNull(response); + assertEquals("", response.getDmlStatement()); + } + + @Test + public void testGetDMLStatement_MissingTableMapping() { + Schema schema = new Schema(); + schema.setSpannerToID(null); + DMLGeneratorRequest dmlGeneratorRequest = + new DMLGeneratorRequest.Builder("insert", "text", null, null, null) + .setSchema(schema) + .build(); + DMLGeneratorResponse response = cassandraDMLGenerator.getDMLStatement(dmlGeneratorRequest); + assertNotNull(response); + assertEquals("", response.getDmlStatement()); + } + + @Test + public void tableAndAllColumnNameTypesMatch() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"LastName\":\"ll\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"SingerId\":\"999\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("SingerId")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + 999, + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertEquals( + "ll", + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value())); + } + + @Test + public void tableAndAllColumnNameTypesForNullValueMatch() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "sample_table"; + String newValueStr = "{\"date_column\":null}"; + JSONObject newValuesJson = new JSONObject(newValueStr); + String keyValueString = "{\"id\":\"999\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("id")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + "999", + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertTrue(values.get(1).value() instanceof CassandraTypeHandler.NullClass); + } + + @Test + public void tableNameMatchSourceColumnNotPresentInSpanner() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"SingerId\":\"999\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("LastName")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + 999, + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertEquals( + "ll", + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value())); + } + + @Test + public void tableNameMatchSpannerColumnNotPresentInSource() { + + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\",\"hb_shardId\":\"shardA\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"SingerId\":\"999\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("LastName")); + assertEquals(4, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + 999, + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertEquals( + "ll", + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value())); + assertEquals( + "shardA", + CassandraTypeHandler.castToExpectedType(values.get(2).dataType(), values.get(2).value())); + } + + @Test + public void primaryKeyNotFoundInJson() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"SomeRandomName\":\"999\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.isEmpty()); + } + + @Test + public void primaryKeyNotPresentInSourceSchema() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"musicId\":\"999\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.isEmpty()); + } + + @Test + public void primaryKeyMismatch() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"SingerId\":\"999\",\"LastName\":\"ll\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"FirstName\":\"kk\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("SingerId")); + assertTrue(sql.contains("LastName")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + 999, + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertEquals( + "ll", + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value())); + } + + @Test + public void deleteMultiplePKColumns() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"LastName\":null}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"SingerId\":\"999\",\"FirstName\":\"kk\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "DELETE"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + 999, + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value())); + } + + @Test + public void testSingleQuoteMatch() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"FirstName\":\"k\u0027k\",\"LastName\":\"ll\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"SingerId\":\"999\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("LastName")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + 999, + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertEquals( + "ll", + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value())); + } + + @Test + public void singleQuoteBytesDML() throws Exception { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + + String tableName = "sample_table"; + String newValuesString = "{\"blob_column\":\"Jw\u003d\u003d\",\"string_column\":\"\u0027\",}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"id\":\"12\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + "12", + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertTrue( + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value()) + instanceof ByteBuffer); + } + + @Test + public void testParseBlobType_hexString() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + + String tableName = "sample_table"; + String newValuesString = "{\"blob_column\":\"0102030405\",\"string_column\":\"\u0027\",}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"id\":\"12\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + "12", + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertTrue( + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value()) + instanceof ByteBuffer); + } + + @Test + public void testParseBlobType_base64String() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + + String tableName = "sample_table"; + String newValuesString = "{\"blob_column\":\"AQIDBAU=\",\"string_column\":\"\u0027\",}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"id\":\"12\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + "12", + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertTrue( + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value()) + instanceof ByteBuffer); + } + + @Test + public void twoSingleEscapedQuoteDML() throws Exception { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + + String tableName = "sample_table"; + String newValuesString = "{\"blob_column\":\"Jyc\u003d\",\"string_column\":\"\u0027\u0027\",}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"id\":\"12\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + assertTrue(sql.contains("sample_table")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + "12", + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertTrue( + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value()) + instanceof ByteBuffer); + } + + @Test + public void threeEscapesAndSingleQuoteDML() throws Exception { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + + String tableName = "sample_table"; + String newValuesString = "{\"blob_column\":\"XCc\u003d\",\"string_column\":\"\\\\\\\u0027\",}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"id\":\"12\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("sample_table")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + "12", + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertTrue( + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value()) + instanceof ByteBuffer); + } + + @Test + public void tabEscapeDML() throws Exception { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + + String tableName = "sample_table"; + String newValuesString = "{\"blob_column\":\"CQ==\",\"string_column\":\"\\t\",}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"id\":\"12\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("sample_table")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + "12", + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertTrue( + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value()) + instanceof ByteBuffer); + } + + @Test + public void backSpaceEscapeDML() throws Exception { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + + String tableName = "sample_table"; + String newValuesString = "{\"blob_column\":\"CA==\",\"string_column\":\"\\b\",}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"id\":\"12\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("sample_table")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + "12", + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertTrue( + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value()) + instanceof ByteBuffer); + } + + @Test + public void newLineEscapeDML() throws Exception { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + + String tableName = "sample_table"; + String newValuesString = "{\"blob_column\":\"Cg==\",\"string_column\":\"\\n\",}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"id\":\"12\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("sample_table")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + "12", + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertTrue( + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value()) + instanceof ByteBuffer); + } + + @Test + public void bitColumnSql() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"YmlsX2NvbA\u003d\u003d\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"SingerId\":\"999\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("LastName")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + 999, + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertEquals( + "YmlsX2NvbA==", + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value())); + } + + @Test + public void testSpannerKeyIsNull() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"SingerId\":null}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("LastName")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals(CassandraTypeHandler.NullClass.INSTANCE, values.get(0).value()); + assertEquals( + "ll", + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value())); + } + + @Test + public void testSourcePKNotInSpanner() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "customer"; + String newValuesString = "{\"Does\":\"not\",\"matter\":\"junk\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"Dont\":\"care\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "DELETE"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.isEmpty()); + } + + @Test + public void primaryKeyMismatchSpannerNull() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"SingerId\":\"999\",\"LastName\":\"ll\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"FirstName\":null}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("SingerId")); + assertTrue(sql.contains("LastName")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + 999, + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertEquals( + "ll", + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value())); + } + + @Test + public void testUnsupportedModType() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"SingerId\":\"999\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "JUNK"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.isEmpty()); + } + + @Test + public void testUpdateModType() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"SingerId\":\"999\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "UPDATE"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.contains("SingerId")); + assertTrue(sql.contains("LastName")); + assertEquals(3, ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues().size()); + List> values = + ((PreparedStatementGeneratedResponse) dmlGeneratorResponse).getValues(); + assertEquals( + 999, + CassandraTypeHandler.castToExpectedType(values.get(0).dataType(), values.get(0).value())); + assertEquals( + "ll", + CassandraTypeHandler.castToExpectedType(values.get(1).dataType(), values.get(1).value())); + } + + @Test + public void testSpannerTableIdMismatch() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + String newValuesString = "{\"Does\":\"not\",\"matter\":\"junk\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"Dont\":\"care\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "DELETE"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + assertTrue(sql.isEmpty()); + } + + @Test + public void testSourcePkNull() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Persons"; + String newValuesString = "{\"Does\":\"not\",\"matter\":\"junk\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"Dont\":\"care\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.isEmpty()); + } + + @Test + public void testSpannerTableNotInSchemaObject() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + schema.getSpSchema().remove(schema.getSpannerToID().get(tableName).getName()); + String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\",\"SingerId\":null}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"SmthingElse\":null}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + + assertTrue(sql.isEmpty()); + } + + @Test + public void testSpannerColDefsNull() { + Schema schema = SessionFileReader.read("src/test/resources/cassandraSession.json"); + String tableName = "Singers"; + + String spannerTableId = schema.getSpannerToID().get(tableName).getName(); + SpannerTable spannerTable = schema.getSpSchema().get(spannerTableId); + spannerTable.getColDefs().remove("c5"); + String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\"}"; + JSONObject newValuesJson = new JSONObject(newValuesString); + String keyValueString = "{\"SingerId\":\"23\"}"; + JSONObject keyValuesJson = new JSONObject(keyValueString); + String modType = "INSERT"; + + CassandraDMLGenerator cassandraDMLGenerator = new CassandraDMLGenerator(); + DMLGeneratorResponse dmlGeneratorResponse = + cassandraDMLGenerator.getDMLStatement( + new DMLGeneratorRequest.Builder( + modType, tableName, newValuesJson, keyValuesJson, "+00:00") + .setSchema(schema) + .setCommitTimestamp(Timestamp.now()) + .build()); + String sql = dmlGeneratorResponse.getDmlStatement(); + CassandraDMLGenerator test = new CassandraDMLGenerator(); + InputRecordProcessor test2 = new InputRecordProcessor(); + assertTrue(sql.isEmpty()); + } + + public static Schema getSchemaObject() { + Map syntheticPKeys = new HashMap(); + Map srcSchema = new HashMap(); + Map spSchema = getSampleSpSchema(); + Map spannerToID = getSampleSpannerToId(); + Schema expectedSchema = new Schema(spSchema, syntheticPKeys, srcSchema); + expectedSchema.setSpannerToID(spannerToID); + return expectedSchema; + } + + public static Map getSampleSpSchema() { + Map spSchema = new HashMap(); + Map t1SpColDefs = + new HashMap(); + t1SpColDefs.put( + "c1", new SpannerColumnDefinition("accountId", new SpannerColumnType("STRING", false))); + t1SpColDefs.put( + "c2", new SpannerColumnDefinition("accountName", new SpannerColumnType("STRING", false))); + t1SpColDefs.put( + "c3", + new SpannerColumnDefinition("migration_shard_id", new SpannerColumnType("STRING", false))); + t1SpColDefs.put( + "c4", new SpannerColumnDefinition("accountNumber", new SpannerColumnType("INT", false))); + spSchema.put( + "t1", + new SpannerTable( + "tableName", + new String[] {"c1", "c2", "c3", "c4"}, + t1SpColDefs, + new ColumnPK[] {new ColumnPK("c1", 1)}, + "c3")); + return spSchema; + } + + public static Map getSampleSpannerToId() { + Map spannerToId = new HashMap(); + Map t1ColIds = new HashMap(); + t1ColIds.put("accountId", "c1"); + t1ColIds.put("accountName", "c2"); + t1ColIds.put("migration_shard_id", "c3"); + t1ColIds.put("accountNumber", "c4"); + spannerToId.put("tableName", new NameAndCols("t1", t1ColIds)); + return spannerToId; + } +} diff --git a/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraTypeHandlerTest.java b/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraTypeHandlerTest.java index 33bd3cfece..463fc5589d 100644 --- a/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraTypeHandlerTest.java +++ b/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/dml/CassandraTypeHandlerTest.java @@ -15,72 +15,43 @@ */ package com.google.cloud.teleport.v2.templates.dbutils.dml; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.convertToCassandraDate; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.convertToCassandraTimestamp; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.convertToSmallInt; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.convertToTinyInt; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.escapeCassandraString; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleBoolSetTypeString; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleByteArrayType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleByteSetType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraAsciiType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraBigintType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraBlobType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraBoolType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraDateType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraDoubleType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraDurationType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraFloatType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraInetAddressType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraIntType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraTextType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraTimestampType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraUuidType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleCassandraVarintType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleDateSetType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleFloat64ArrayType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleFloatArrayType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleFloatSetType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleInt64ArrayAsInt32Array; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleInt64ArrayAsInt32Set; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleInt64SetType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleStringArrayType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleStringSetType; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleStringifiedJsonToMap; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.handleStringifiedJsonToSet; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.isValidIPAddress; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.isValidJSON; -import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.isValidUUID; +import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.castToExpectedType; +import static com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraTypeHandler.getColumnValueByType; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - +import static org.mockito.Mockito.mock; + +import com.google.cloud.teleport.v2.spanner.migrations.schema.SourceColumnDefinition; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SourceColumnType; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SpannerColumnDefinition; +import com.google.cloud.teleport.v2.spanner.migrations.schema.SpannerColumnType; +import com.google.cloud.teleport.v2.templates.models.PreparedStatementValueObject; +import com.google.common.net.InetAddresses; +import java.math.BigDecimal; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.ByteBuffer; -import java.sql.Timestamp; import java.time.Duration; import java.time.Instant; import java.time.LocalDate; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; import java.util.Arrays; -import java.util.Base64; -import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import org.json.JSONArray; import org.json.JSONObject; -import org.junit.Assert; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -88,1230 +59,1149 @@ public class CassandraTypeHandlerTest { @Test - public void convertSpannerValueJsonToBooleanType() { - String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\", \"isAdmin\":\"true\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "isAdmin"; - Boolean convertedValue = handleCassandraBoolType(colKey, newValuesJson); - assertTrue(convertedValue); - } + public void testGetColumnValueByTypeForString() { + SpannerColumnType spannerType = new SpannerColumnType("string", false); + SourceColumnType sourceColumnType = new SourceColumnType("varchar", null, null); + String columnName = "test_column"; + String sourceDbTimezoneOffset = null; - @Test - public void convertSpannerValueJsonToBooleanType_False() { - String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\", \"isAdmin\":\"false\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "isAdmin"; - Boolean convertedValue = handleCassandraBoolType(colKey, newValuesJson); - Assert.assertFalse(convertedValue); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test - public void convertSpannerValueJsonToFloatType() { - String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\", \"age\":23.5}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "age"; - Float convertedValue = handleCassandraFloatType(colKey, newValuesJson); - assertEquals(23.5f, convertedValue, 0.01f); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, "test_value"); + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); - @Test - public void convertSpannerValueJsonToDoubleType() { - String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\", \"salary\":100000.75}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "salary"; - Double convertedValue = handleCassandraDoubleType(colKey, newValuesJson); - assertEquals(100000.75, convertedValue, 0.01); + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + assertEquals("test_value", castResult); } @Test - public void convertSpannerValueJsonToBlobType_FromByteArray() { - String newValuesString = - "{\"FirstName\":\"kk\",\"LastName\":\"ll\", \"data\":\"QUJDQDEyMzQ=\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "data"; - ByteBuffer convertedValue = handleCassandraBlobType(colKey, newValuesJson); - byte[] expectedBytes = java.util.Base64.getDecoder().decode("QUJDQDEyMzQ="); - byte[] actualBytes = new byte[convertedValue.remaining()]; - convertedValue.get(actualBytes); - Assert.assertArrayEquals(expectedBytes, actualBytes); - } + public void testGetColumnValueByType() { + String spannerColumnType = "string"; + String sourceType = "varchar"; + SpannerColumnType spannerType = new SpannerColumnType(spannerColumnType, false); + SourceColumnType sourceColumnType = new SourceColumnType(sourceType, null, null); + String columnValue = "é"; + String columnName = "LastName"; + String sourceDbTimezoneOffset = null; - @Rule public ExpectedException expectedEx = ExpectedException.none(); + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test - public void testHandleNullBooleanType() { - String newValuesString = "{\"isAdmin\":null}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "isAdmin"; - assertEquals(false, handleCassandraBoolType(colKey, newValuesJson)); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, columnValue); - @Test - public void testHandleNullFloatType() { - String newValuesString = "{\"age\":null}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "age"; - assertNull(handleCassandraFloatType(colKey, newValuesJson)); - } + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); - @Test - public void testHandleNullDoubleType() { - String newValuesString = "{\"salary\":null}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "salary"; - Double value = handleCassandraDoubleType(colKey, newValuesJson); - assertNull(value); - } + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); - @Test - public void testHandleMaxInteger() { - String newValuesString = "{\"age\":2147483647}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "age"; - Integer value = handleCassandraIntType(colKey, newValuesJson); - assertEquals(Integer.MAX_VALUE, value.longValue()); + assertEquals("é", castResult); } @Test - public void testHandleMinInteger() { - String newValuesString = "{\"age\":-2147483648}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "age"; - Integer value = handleCassandraIntType(colKey, newValuesJson); - assertEquals(Integer.MIN_VALUE, value.longValue()); - } + public void testGetColumnValueByTypeForNumericToInt() { + String spannerColumnName = "NUMERIC"; + String sourceColumnName = "int"; + SpannerColumnType spannerType = new SpannerColumnType(spannerColumnName, false); + SourceColumnType sourceColumnType = new SourceColumnType(sourceColumnName, null, null); + String columnName = "Salary"; + String sourceDbTimezoneOffset = null; - @Test - public void testHandleMaxLong() { - String newValuesString = "{\"age\":9223372036854775807}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "age"; - Long value = handleCassandraBigintType(colKey, newValuesJson); - assertEquals(Long.MAX_VALUE, value.longValue()); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test - public void testHandleMinLong() { - String newValuesString = "{\"age\":-9223372036854775808}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "age"; - Long value = handleCassandraBigintType(colKey, newValuesJson); - assertEquals(Long.MIN_VALUE, value.longValue()); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, 12345); + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); - @Test - public void testHandleMaxFloat() { - String newValuesString = "{\"value\":3.4028235E38}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "value"; - Float value = handleCassandraFloatType(colKey, newValuesJson); - assertEquals(Float.MAX_VALUE, value, 0.01f); - } + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); - @Test - public void testHandleMinFloat() { - String newValuesString = "{\"value\":-3.4028235E38}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "value"; - Float value = handleCassandraFloatType(colKey, newValuesJson); - assertEquals(-Float.MAX_VALUE, value, 0.01f); + assertEquals(12345, castResult); } @Test - public void testHandleMaxDouble() { - String newValuesString = "{\"value\":1.7976931348623157E308}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "value"; - Double value = handleCassandraDoubleType(colKey, newValuesJson); - assertEquals(Double.MAX_VALUE, value, 0.01); - } + public void testGetColumnValueByTypeForStringUUID() { + SpannerColumnType spannerType = new SpannerColumnType("string", false); + SourceColumnType sourceColumnType = new SourceColumnType("uuid", null, null); + String columnName = "id"; + String columnValue = "123e4567-e89b-12d3-a456-426614174000"; + String sourceDbTimezoneOffset = null; - @Test - public void testHandleMinDouble() { - String newValuesString = "{\"value\":-1.7976931348623157E308}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "value"; - Double value = handleCassandraDoubleType(colKey, newValuesJson); - assertEquals(-Double.MAX_VALUE, value, 0.01); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test - public void testHandleInvalidIntegerFormat() { - String newValuesString = "{\"age\":\"invalid_integer\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "age"; - handleCassandraIntType(colKey, newValuesJson); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, columnValue); - @Test - public void testHandleInvalidLongFormat() { - String newValuesString = "{\"age\":\"invalid_long\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "age"; - handleCassandraBigintType(colKey, newValuesJson); - } + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); - @Test - public void testHandleInvalidFloatFormat() { - String newValuesString = "{\"value\":\"invalid_float\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "value"; - handleCassandraFloatType(colKey, newValuesJson); + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(UUID.fromString(columnValue), castResult); } @Test - public void testHandleInvalidDoubleFormat() { - String newValuesString = "{\"value\":\"invalid_double\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "value"; - handleCassandraDoubleType(colKey, newValuesJson); - } + public void testGetColumnValueByTypeForStringIpAddress() { + SpannerColumnType spannerType = new SpannerColumnType("string", false); + SourceColumnType sourceColumnType = new SourceColumnType("inet", null, null); + String columnValue = "192.168.1.1"; + String columnName = "ipAddress"; + String sourceDbTimezoneOffset = null; - @Test(expected = IllegalArgumentException.class) - public void testHandleInvalidBlobFormat() { - String newValuesString = "{\"data\":\"not_base64\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "data"; - handleCassandraBlobType(colKey, newValuesJson); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test(expected = IllegalArgumentException.class) - public void testHandleInvalidDateFormat() { - String newValuesString = "{\"birthdate\":\"invalid_date_format\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "birthdate"; - handleCassandraDateType(colKey, newValuesJson); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, columnValue); - @Test - public void testHandleNullTextType() { - String newValuesString = "{\"name\":null}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "name"; - String value = handleCassandraTextType(colKey, newValuesJson); - assertNull(value); + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(InetAddresses.forString(columnValue), castResult); } @Test - public void testHandleUnsupportedBooleanType() { - String newValuesString = "{\"values\":[true, false]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); + public void testGetColumnValueByTypeForStringJsonArray() { + SpannerColumnType spannerType = new SpannerColumnType("string", false); + SourceColumnType sourceColumnType = new SourceColumnType("set", null, null); + String columnValue = "[\"apple\", \"banana\", \"cherry\"]"; + String columnName = "fruits"; + String sourceDbTimezoneOffset = null; + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, columnValue); - expectedEx.expect(IllegalArgumentException.class); - expectedEx.expectMessage("Unsupported type for column values"); + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); - handleFloatSetType("values", newValuesJson); + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + Set expectedSet = new HashSet<>(Arrays.asList("apple", "banana", "cherry")); + assertEquals(expectedSet, castResult); } @Test - public void testHandleUnsupportedListType() { - String newValuesString = "{\"values\":[[1, 2], [3, 4]]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); + public void testGetColumnValueByTypeForStringJsonObject() { + SpannerColumnType spannerType = new SpannerColumnType("string", false); + SourceColumnType sourceColumnType = new SourceColumnType("map", null, null); + String columnName = "user"; + String columnValue = "{\"name\": \"John\", \"age\": \"30\"}"; + String sourceDbTimezoneOffset = null; - expectedEx.expect(IllegalArgumentException.class); - expectedEx.expectMessage("Unsupported type for column values"); + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - handleFloatSetType("values", newValuesJson); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, columnValue); - @Test - public void testHandleUnsupportedMapType() { - String newValuesString = "{\"values\":[{\"key1\":\"value1\"}, {\"key2\":\"value2\"}]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); - expectedEx.expect(IllegalArgumentException.class); - expectedEx.expectMessage("Unsupported type for column values"); + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); - handleFloatSetType("values", newValuesJson); + Map expectedMap = new HashMap<>(); + expectedMap.put("name", "John"); + expectedMap.put("age", "30"); + assertEquals(expectedMap, castResult); } @Test - public void testHandleUnsupportedType() { - String newValuesString = "{\"values\":[true, false]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); + public void testGetColumnValueByTypeForStringHex() { + SpannerColumnType spannerType = new SpannerColumnType("bytes", false); + SourceColumnType sourceColumnType = new SourceColumnType("blob", null, null); + String columnName = "lastName"; + byte[] expectedBytes = new byte[] {1, 2, 3, 4, 5}; + StringBuilder binaryString = new StringBuilder(); + for (byte b : expectedBytes) { + binaryString.append(String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0')); + } + String columnValue = binaryString.toString(); + String sourceDbTimezoneOffset = null; - expectedEx.expect(IllegalArgumentException.class); - expectedEx.expectMessage("Unsupported type for column values"); + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - handleFloatSetType("values", newValuesJson); + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, columnValue); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + byte[] actualBytes; + if (castResult instanceof ByteBuffer) { + ByteBuffer byteBuffer = (ByteBuffer) castResult; + actualBytes = new byte[byteBuffer.remaining()]; + byteBuffer.get(actualBytes); + } else if (castResult instanceof byte[]) { + actualBytes = (byte[]) castResult; + } else { + throw new AssertionError("Unexpected type for castResult"); + } + assertArrayEquals(expectedBytes, actualBytes); } @Test - public void convertSpannerValueJsonToBlobType_FromBase64() { - String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\", \"data\":\"QUJDRA==\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "data"; - ByteBuffer convertedValue = handleCassandraBlobType(colKey, newValuesJson); - byte[] expectedBytes = Base64.getDecoder().decode("QUJDRA=="); - byte[] actualBytes = new byte[convertedValue.remaining()]; - convertedValue.get(actualBytes); - Assert.assertArrayEquals(expectedBytes, actualBytes); - } + public void testGetColumnValueByTypeForBlobEncodeInStringHexToBlob() { + SpannerColumnType spannerType = new SpannerColumnType("bytes", false); + SourceColumnType sourceColumnType = new SourceColumnType("blob", null, null); + String columnName = "lastName"; + byte[] expectedBytes = new byte[] {1, 2, 3, 4, 5}; + StringBuilder binaryString = new StringBuilder(); + for (byte b : expectedBytes) { + binaryString.append(String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0')); + } + String columnValue = binaryString.toString(); + String sourceDbTimezoneOffset = null; - @Test - public void convertSpannerValueJsonToBlobType_EmptyString() { - String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\", \"data\":\"\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "data"; - ByteBuffer convertedValue = handleCassandraBlobType(colKey, newValuesJson); - Assert.assertNotNull(convertedValue); - assertEquals(0, convertedValue.remaining()); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test(expected = IllegalArgumentException.class) - public void convertSpannerValueJsonToBlobType_InvalidType() { - String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\", \"data\":12345}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "data"; - handleCassandraBlobType(colKey, newValuesJson); + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, columnValue); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + byte[] actualBytes; + if (castResult instanceof ByteBuffer) { + ByteBuffer byteBuffer = (ByteBuffer) castResult; + actualBytes = new byte[byteBuffer.remaining()]; + byteBuffer.get(actualBytes); + } else if (castResult instanceof byte[]) { + actualBytes = (byte[]) castResult; + } else { + throw new AssertionError("Unexpected type for castResult"); + } + assertArrayEquals(expectedBytes, actualBytes); } @Test - public void convertSpannerValueJsonToInvalidFloatType() { - String newValuesString = - "{\"FirstName\":\"kk\",\"LastName\":\"ll\", \"age\":\"invalid_value\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "age"; - handleCassandraFloatType(colKey, newValuesJson); - } + public void testGetColumnValueByTypeForStringDuration() { + SpannerColumnType spannerType = new SpannerColumnType("string", false); + SourceColumnType sourceColumnType = new SourceColumnType("duration", null, null); + String columnValue = "P4DT1H"; + String columnName = "total_time"; + String sourceDbTimezoneOffset = null; - @Test - public void convertSpannerValueJsonToInvalidDoubleType() { - String newValuesString = - "{\"FirstName\":\"kk\",\"LastName\":\"ll\", \"salary\":\"invalid_value\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "salary"; - handleCassandraDoubleType(colKey, newValuesJson); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test - public void convertSpannerValueJsonToBlobType_MissingColumn() { - String newValuesString = "{\"FirstName\":\"kk\",\"LastName\":\"ll\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "data"; - ByteBuffer convertedValue = handleCassandraBlobType(colKey, newValuesJson); - Assert.assertNull(convertedValue); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, columnValue); - @Test - public void testHandleByteArrayType() { - String newValuesString = "{\"data\":[\"QUJDRA==\", \"RkZIRg==\"]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - List value = handleByteArrayType("data", newValuesJson); - - List expected = - Arrays.asList( - ByteBuffer.wrap(Base64.getDecoder().decode("QUJDRA==")), - ByteBuffer.wrap(Base64.getDecoder().decode("RkZIRg=="))); - assertEquals(expected, value); - } + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); - @Test - public void testHandleByteSetType() { - String newValuesString = "{\"data\":[\"QUJDRA==\", \"RkZIRg==\"]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - Set value = handleByteSetType("data", newValuesJson); - - Set expected = - new HashSet<>( - Arrays.asList( - ByteBuffer.wrap(Base64.getDecoder().decode("QUJDRA==")), - ByteBuffer.wrap(Base64.getDecoder().decode("RkZIRg==")))); - assertEquals(expected, value); + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(Duration.parse("P4DT1H"), castResult); } @Test - public void testHandleStringArrayType() { - String newValuesString = "{\"names\":[\"Alice\", \"Bob\", \"Charlie\"]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - List value = handleStringArrayType("names", newValuesJson); + public void testGetColumnValueByTypeForDates() { + SpannerColumnType spannerType = new SpannerColumnType("date", false); + SourceColumnType sourceColumnType = new SourceColumnType("timestamp", null, null); + String columnValue = "2025-01-01T00:00:00Z"; + String columnName = "created_on"; + String sourceDbTimezoneOffset = null; - List expected = Arrays.asList("Alice", "Bob", "Charlie"); - assertEquals(expected, value); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test - public void testHandleStringSetType() { - String newValuesString = "{\"names\":[\"Alice\", \"Bob\", \"Alice\", \"Charlie\"]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - Set valueList = handleStringSetType("names", newValuesJson); - HashSet value = new HashSet<>(valueList); - HashSet expected = new HashSet<>(Arrays.asList("Alice", "Bob", "Charlie")); - assertEquals(expected, value); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, columnValue); - @Test - public void testHandleBoolSetTypeString() { - String newValuesString = "{\"flags\":[\"true\", \"false\", \"true\"]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - Set value = handleBoolSetTypeString("flags", newValuesJson); + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); - Set expected = new HashSet<>(Arrays.asList(true, false)); - assertEquals(expected, value); + ZonedDateTime expectedDate = ZonedDateTime.parse(columnValue).withSecond(0).withNano(0); + Instant instant = (Instant) castResult; + ZonedDateTime actualDate = instant.atZone(ZoneOffset.UTC).withSecond(0).withNano(0); + assertEquals(expectedDate, actualDate); } @Test - public void testHandleFloatArrayType() { - String newValuesString = "{\"values\":[1.1, 2.2, 3.3]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - List value = handleFloatArrayType("values", newValuesJson); + public void testGetColumnValueByTypeForBigInt() { + SpannerColumnType spannerType = new SpannerColumnType("bigint", false); + SourceColumnType sourceColumnType = new SourceColumnType("bigint", null, null); + String columnName = "Salary"; + String sourceDbTimezoneOffset = null; - List expected = Arrays.asList(1.1f, 2.2f, 3.3f); - assertEquals(expected, value); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test - public void testHandleFloatSetType() { - String newValuesString = "{\"values\":[1.1, 2.2, 3.3, 2.2]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - Set value = handleFloatSetType("values", newValuesJson); + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, BigInteger.valueOf(123456789L)); - Set expected = new HashSet<>(Arrays.asList(1.1f, 2.2f, 3.3f)); - assertEquals(expected, value); - } + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); - @Test - public void testHandleFloatSetType_InvalidString() { - String newValuesString = "{\"values\":[\"1.1\", \"2.2\", \"abc\"]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - try { - handleFloatSetType("values", newValuesJson); - fail("Expected IllegalArgumentException for invalid number format"); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().contains("Invalid number format for column values")); - } + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + Long expectedBigInt = 123456789L; + + assertEquals(expectedBigInt, castResult); } @Test - public void testHandleFloat64ArrayType() { - String newValuesString = "{\"values\":[1.1, \"2.2\", 3.3]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - List value = handleFloat64ArrayType("values", newValuesJson); + public void testGetColumnValueByTypeForBytesForHexString() { + SpannerColumnType spannerType = new SpannerColumnType("String", false); + SourceColumnType sourceColumnType = new SourceColumnType("bytes", null, null); + String columnName = "Name"; + String sourceDbTimezoneOffset = null; - List expected = Arrays.asList(1.1, 2.2, 3.3); - assertEquals(expected, value); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test(expected = IllegalArgumentException.class) - public void testHandleFloat64ArrayTypeInvalid() { - String newValuesString = "{\"values\":[\"1.1\", \"abc\", \"3.3\"]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - handleFloat64ArrayType("values", newValuesJson); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, "48656c6c6f20576f726c64"); - @Test - public void testHandleDateSetType() { - String newValuesString = "{\"dates\":[\"2024-12-05\", \"2024-12-06\"]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - Set value = handleDateSetType("dates", newValuesJson); - Set expected = - new HashSet<>(Arrays.asList(LocalDate.of(2024, 12, 5), LocalDate.of(2024, 12, 6))); - assertEquals(expected, value); - } + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); - @Test(expected = IllegalArgumentException.class) - public void testHandleFloat64ArrayType_WithUnsupportedList() { - String jsonStr = "{\"colName\": [[1, 2, 3], [4, 5, 6]]}"; - JSONObject valuesJson = new JSONObject(jsonStr); - CassandraTypeHandler.handleFloat64ArrayType("colName", valuesJson); - } + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); - @Test - public void testHandleInt64SetType_ValidLongValues() { - String newValuesString = "{\"numbers\":[1, 2, 3, 4]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - Set result = handleInt64SetType("numbers", newValuesJson); - Set expected = new HashSet<>(Arrays.asList(1L, 2L, 3L, 4L)); - assertEquals(expected, result); + assertEquals("48656c6c6f20576f726c64", castResult); } @Test - public void testHandleCassandraIntType_ValidInteger() { - String newValuesString = "{\"age\":1234}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - Integer result = handleCassandraIntType("age", newValuesJson); - Integer expected = 1234; - assertEquals(expected, result); - } + public void testGetColumnValueByTypeForBigIntForString() { + SpannerColumnType spannerType = new SpannerColumnType("String", false); + SourceColumnType sourceColumnType = new SourceColumnType("bigint", null, null); + String columnName = "Salary"; + String sourceDbTimezoneOffset = null; - @Test - public void testHandleCassandraBigintType_ValidConversion() { - String newValuesString = "{\"age\":1234567890123}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - Long result = handleCassandraBigintType("age", newValuesJson); - Long expected = 1234567890123L; - assertEquals(expected, result); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test - public void testHandleInt64ArrayAsInt32Array() { - String newValuesString = "{\"values\":[1, 2, 3, 4]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - List value = handleInt64ArrayAsInt32Array("values", newValuesJson); + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, "123456789"); - List expected = Arrays.asList(1, 2, 3, 4); - assertEquals(expected, value); - } + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); - @Test - public void testHandleInt64ArrayAsInt32Set() { - String newValuesString = "{\"values\":[1, 2, 3, 2]}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - Set value = handleInt64ArrayAsInt32Set("values", newValuesJson); + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); - Set expected = new HashSet<>(Arrays.asList(1, 2, 3)); - assertEquals(expected, value); + long expectedValue = 123456789L; + assertEquals(expectedValue, castResult); } @Test - public void testHandleCassandraUuidTypeNull() { - String newValuesString = "{\"uuid\":null}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - UUID value = handleCassandraUuidType("uuid", newValuesJson); - Assert.assertNull(value); - } + public void testGetColumnValueByTypeForBoolentForString() { + SpannerColumnType spannerType = new SpannerColumnType("String", false); + SourceColumnType sourceColumnType = new SourceColumnType("boolean", null, null); + String columnName = "Male"; + String sourceDbTimezoneOffset = null; - @Test(expected = IllegalArgumentException.class) - public void testHandleCassandraTimestampInvalidFormat() { - String newValuesString = "{\"createdAt\":\"2024-12-05 10:15:30.123\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - handleCassandraTimestampType("createdAt", newValuesJson); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test(expected = IllegalArgumentException.class) - public void testHandleCassandraTimestampInvalidFormatColNull() { - String newValuesString = "{\"createdAt\":\"2024-12-05 10:15:30.123\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - handleCassandraTimestampType("timestamp", newValuesJson); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, "1"); - @Test(expected = IllegalArgumentException.class) - public void testHandleCassandraDateInvalidFormat() { - String newValuesString = "{\"birthdate\":\"2024/12/05\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - handleCassandraDateType("birthdate", newValuesJson); - } + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); - @Test - public void testHandleCassandraTextTypeNull() { - String newValuesString = "{\"name\":null}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String value = handleCassandraTextType("name", newValuesJson); - Assert.assertNull(value); - } + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); - @Test - public void testHandleBoolArrayType_ValidBooleanStrings() { - String jsonStr = "{\"colName\": [\"true\", \"false\", \"true\"]}"; - JSONObject valuesJson = new JSONObject(jsonStr); - List result = CassandraTypeHandler.handleBoolArrayType("colName", valuesJson); - assertEquals(3, result.size()); - assertTrue(result.get(0)); - assertFalse(result.get(1)); - assertTrue(result.get(2)); + assertEquals(true, castResult); } @Test - public void testHandleBoolArrayType_InvalidBooleanStrings() { - String jsonStr = "{\"colName\": [\"yes\", \"no\", \"true\"]}"; - JSONObject valuesJson = new JSONObject(jsonStr); - List result = CassandraTypeHandler.handleBoolArrayType("colName", valuesJson); - assertEquals(3, result.size()); - assertFalse(result.get(0)); - assertFalse(result.get(1)); - assertTrue(result.get(2)); - } + public void testGetColumnValueByTypeForBoolent() { + SpannerColumnType spannerType = new SpannerColumnType("Boolean", false); + SourceColumnType sourceColumnType = new SourceColumnType("boolean", null, null); + String columnName = "Male"; + String sourceDbTimezoneOffset = null; - @Test - public void testHandleBoolArrayType_EmptyArray() { - String jsonStr = "{\"colName\": []}"; - JSONObject valuesJson = new JSONObject(jsonStr); - List result = CassandraTypeHandler.handleBoolArrayType("colName", valuesJson); - assertTrue(result.isEmpty()); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test - public void testHandleTimestampSetType_validArray() { - String jsonString = - "{\"timestamps\": [\"2024-12-04T12:34:56.123Z\", \"2024-12-05T13:45:00.000Z\"]}"; - JSONObject valuesJson = new JSONObject(jsonString); + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, false); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); - Set result = CassandraTypeHandler.handleTimestampSetType("timestamps", valuesJson); + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); - assertNotNull(result); - assertEquals(2, result.size()); - assertTrue(result.contains(Timestamp.valueOf("2024-12-04 00:00:00.0"))); - assertTrue(result.contains(Timestamp.valueOf("2024-12-05 00:00:00.0"))); + assertEquals(false, castResult); } @Test - public void testHandleValidAsciiString() { - String newValuesString = "{\"name\":\"JohnDoe\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "name"; - assertEquals("JohnDoe", handleCassandraAsciiType(colKey, newValuesJson)); - } + public void testGetColumnValueByTypeForIntegerValue() { + SpannerColumnType spannerType = new SpannerColumnType("Integer", false); + SourceColumnType sourceColumnType = new SourceColumnType("bigint", null, null); + String columnName = "Salary"; + String sourceDbTimezoneOffset = null; - @Test(expected = IllegalArgumentException.class) - public void testHandleNonAsciiString() { - String newValuesString = "{\"name\":\"JoãoDoe\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "name"; - handleCassandraAsciiType(colKey, newValuesJson); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); - @Test - public void testHandleNullForAsciiColumn() { - String newValuesString = "{\"name\":null}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "name"; - handleCassandraAsciiType(colKey, newValuesJson); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, 225000); - @Test - public void testHandleValidStringVarint() { - String newValuesString = "{\"amount\":\"123456789123456789\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "amount"; - BigInteger expected = new BigInteger("123456789123456789"); - assertEquals(expected, handleCassandraVarintType(colKey, newValuesJson)); - } + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); - @Test(expected = IllegalArgumentException.class) - public void testHandleInvalidStringVarint() { - String newValuesString = "{\"amount\":\"abcxyz\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "amount"; - handleCassandraVarintType(colKey, newValuesJson); - } + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); - @Test - public void testHandleInvalidTypeVarint() { - String newValuesString = "{\"amount\":12345}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "amount"; - handleCassandraVarintType(colKey, newValuesJson); + long expectedValue = 225000L; + assertEquals(expectedValue, castResult); } @Test - public void testHandleValidDuration() { - String newValuesString = "{\"duration\":\"P1DT1H\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "duration"; - Duration expected = Duration.parse("P1DT1H"); - assertEquals(expected, handleCassandraDurationType(colKey, newValuesJson)); + public void testGetColumnValueByTypeForBoolentSamllCaseForString() { + SpannerColumnType spannerType = new SpannerColumnType("String", false); + SourceColumnType sourceColumnType = new SourceColumnType("boolean", null, null); + String columnName = "Male"; + String sourceDbTimezoneOffset = null; + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColumnType); + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, "f"); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, sourceDbTimezoneOffset); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(false, castResult); } + // Revised and Improved Tests + @Test - public void testHandleNullDuration() { - String newValuesString = "{\"duration\":null}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "duration"; - assertNull(handleCassandraDurationType(colKey, newValuesJson)); + public void testGetColumnValueByTypeForInteger() { + SpannerColumnType spannerType = new SpannerColumnType("NUMERIC", false); + SourceColumnType sourceColType = new SourceColumnType("integer", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, BigInteger.valueOf(5)); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, null); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(BigInteger.valueOf(5), castResult); } @Test - public void testHandleMissingColumnKey() { - String newValuesString = "{\"otherColumn\":\"P1DT1H\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "duration"; - assertNull(handleCassandraDurationType(colKey, newValuesJson)); + public void testGetColumnValueByTypeForValidBigInteger() { + SpannerColumnType spannerType = new SpannerColumnType("integer", false); + SourceColumnType sourceColType = new SourceColumnType("int64", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, BigInteger.valueOf(5)); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, null); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(BigInteger.valueOf(5), castResult); } @Test - public void testHandleValidIPv4Address() throws UnknownHostException { - String newValuesString = "{\"ipAddress\":\"192.168.0.1\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "ipAddress"; - InetAddress expected = InetAddress.getByName("192.168.0.1"); - assertEquals(expected, handleCassandraInetAddressType(colKey, newValuesJson)); + public void testConvertToCassandraTimestampWithISOInstant() { + String timestamp = "2025-01-15T10:15:30Z"; + SpannerColumnType spannerType = new SpannerColumnType("timestamp", false); + SourceColumnType sourceColType = new SourceColumnType("date", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, timestamp); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, null); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + LocalDate expectedValue = Instant.parse(timestamp).atZone(ZoneId.systemDefault()).toLocalDate(); + assertEquals(expectedValue, castResult); } @Test - public void testHandleValidIPv6Address() throws Exception { - String newValuesString = "{\"ipAddress\":\"2001:0db8:85a3:0000:0000:8a2e:0370:7334\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "ipAddress"; - InetAddress actual = CassandraTypeHandler.handleCassandraInetAddressType(colKey, newValuesJson); - InetAddress expected = InetAddress.getByName("2001:0db8:85a3:0000:0000:8a2e:0370:7334"); - assertEquals(expected, actual); - } + public void testConvertToCassandraTimestampWithISODateTime() { + String timestamp = "2025-01-15T10:15:30"; + SpannerColumnType spannerType = new SpannerColumnType("timestamp", false); + SourceColumnType sourceColType = new SourceColumnType("datetime", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, timestamp); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, null); - @Test(expected = IllegalArgumentException.class) - public void testHandleInvalidIPAddressFormat() throws IllegalArgumentException { - String newValuesString = "{\"ipAddress\":\"invalid-ip-address\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "ipAddress"; - handleCassandraInetAddressType(colKey, newValuesJson); + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals("2025-01-15T00:00:00Z", castResult.toString()); } @Test - public void testHandleEmptyStringIPAddress() { - String newValuesString = "{\"ipAddress\":\"192.168.1.1\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "ipAddress"; - Object result = handleCassandraInetAddressType(colKey, newValuesJson); - assertTrue("Expected result to be of type InetAddress", result instanceof InetAddress); - assertEquals( - "IP address does not match", "192.168.1.1", ((InetAddress) result).getHostAddress()); + public void testConvertToCassandraTimestampWithISODate() { + String timestamp = "2025-01-15"; + SpannerColumnType spannerType = new SpannerColumnType("timestamp", false); + SourceColumnType sourceColType = new SourceColumnType("date", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, timestamp); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, null); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(timestamp, castResult.toString()); } @Test - public void testHandleStringifiedJsonToMapWithEmptyJson() { - String newValuesString = "{}"; - JSONObject newValuesJson = new JSONObject(); - newValuesJson.put("data", newValuesString); - String colKey = "data"; - Map expected = Map.of(); - Map result = handleStringifiedJsonToMap(colKey, newValuesJson); - assertEquals(expected, result); + public void testConvertToCassandraTimestampWithCustomFormat1() { + String timestamp = "01/15/2025"; + SpannerColumnType spannerType = new SpannerColumnType("timestamp", false); + SourceColumnType sourceColType = new SourceColumnType("date", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, timestamp); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, null); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals("2025-01-15", castResult.toString()); } @Test - public void testHandleStringifiedJsonToMapWithSimpleJson() { - String newValuesString = "{\"name\":\"John\", \"age\":30}"; - JSONObject newValuesJson = new JSONObject(); - newValuesJson.put("data", newValuesString); - String colKey = "data"; - Map expected = Map.of("name", "John", "age", 30); - Map result = handleStringifiedJsonToMap(colKey, newValuesJson); - assertEquals(expected, result); - } + public void testConvertToCassandraTimestampWithCustomFormat2() { + String timestamp = "2025/01/15"; + SpannerColumnType spannerType = new SpannerColumnType("timestamp", false); + SourceColumnType sourceColType = new SourceColumnType("date", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, timestamp); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, null); - @Test(expected = IllegalArgumentException.class) - public void testHandleStringifiedJsonToMapWithInvalidJson() { - String newValuesString = "{\"user\":{\"name\":\"John\", \"age\":30"; - JSONObject newValuesJson = new JSONObject(); - newValuesJson.put("data", newValuesString); - String colKey = "data"; - handleStringifiedJsonToMap(colKey, newValuesJson); + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals("2025-01-15", castResult.toString()); } @Test - public void testHandleStringifiedJsonToMapWithNullValues() { - String newValuesString = "{\"name\":null, \"age\":null}"; - JSONObject newValuesJson = new JSONObject(); - newValuesJson.put("data", newValuesString); - String colKey = "data"; - Map expected = - Map.of( - "name", JSONObject.NULL, - "age", JSONObject.NULL); - Map result = handleStringifiedJsonToMap(colKey, newValuesJson); - assertEquals(expected, result); - } + public void testConvertToCassandraTimestampWithCustomFormat3() { + String timestamp = "15-01-2025"; + SpannerColumnType spannerType = new SpannerColumnType("timestamp", false); + SourceColumnType sourceColType = new SourceColumnType("date", null, null); + String columnName = "test_column"; - @Test(expected = IllegalArgumentException.class) - public void testHandleInvalidStringifiedJson() { - String newValuesString = "{\"user\":{\"name\":\"John\", \"age\":30"; - JSONObject newValuesJson = new JSONObject(); - newValuesJson.put("data", newValuesString); - String colKey = "data"; - handleStringifiedJsonToMap(colKey, newValuesJson); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, timestamp); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); - @Test(expected = IllegalArgumentException.class) - public void testHandleNonStringValue() { - JSONObject newValuesJson = new JSONObject(); - newValuesJson.put("data", 12345); - String colKey = "data"; - handleStringifiedJsonToMap(colKey, newValuesJson); + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, null); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals("2025-01-15", castResult.toString()); } @Test - public void testHandleValidStringifiedJsonArray() { - String newValuesString = "[\"apple\", \"banana\", \"cherry\"]"; - JSONObject newValuesJson = new JSONObject(); - newValuesJson.put("data", newValuesString); - String colKey = "data"; - - Set expected = new HashSet<>(); - expected.add("apple"); - expected.add("banana"); - expected.add("cherry"); - assertEquals(expected, handleStringifiedJsonToSet(colKey, newValuesJson)); + public void testConvertToCassandraTimestampWithCustomFormat4() { + String timestamp = "15/01/2025"; + SpannerColumnType spannerType = new SpannerColumnType("timestamp", false); + SourceColumnType sourceColType = new SourceColumnType("date", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, timestamp); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, null); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals("2025-01-15", castResult.toString()); } @Test - public void testHandleEmptyStringifiedJsonArray() { - String newValuesString = "[]"; - JSONObject newValuesJson = new JSONObject(); - newValuesJson.put("data", newValuesString); - String colKey = "data"; - Set expected = new HashSet<>(); - assertEquals(expected, handleStringifiedJsonToSet(colKey, newValuesJson)); + public void testConvertToCassandraTimestampWithCustomFormat5() { + String timestamp = "2025-01-15 10:15:30"; + SpannerColumnType spannerType = new SpannerColumnType("timestamp", false); + SourceColumnType sourceColType = new SourceColumnType("date", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, timestamp); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, null); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals("2025-01-15", castResult.toString()); } @Test - public void testHandleNonArrayValue() { - String newValuesString = "\"apple\""; - JSONObject newValuesJson = new JSONObject(); - newValuesJson.put("data", newValuesString); - String colKey = "data"; + public void testConvertToCassandraTimestampWithInvalidFormat() { + String timestamp = "invalid-timestamp"; + SpannerColumnType spannerType = new SpannerColumnType("timestamp", false); + SourceColumnType sourceColType = new SourceColumnType("date", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, timestamp); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); assertThrows( - IllegalArgumentException.class, () -> handleStringifiedJsonToSet(colKey, newValuesJson)); + IllegalArgumentException.class, + () -> { + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, null); + CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + }); } @Test - public void testConvertToSmallIntValidInput() { - Integer validValue = 100; - short result = convertToSmallInt(validValue); - assertEquals(100, result); - } + public void testConvertToCassandraTimestampWithNull() { + SpannerColumnType spannerType = new SpannerColumnType("timestamp", false); + SourceColumnType sourceColType = new SourceColumnType("date", null, null); + String columnName = "test_column"; - @Test - public void testConvertToSmallIntBelowMinValue() { - Integer invalidValue = Short.MIN_VALUE - 1; - assertThrows(IllegalArgumentException.class, () -> convertToSmallInt(invalidValue)); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, " "); - @Test - public void testConvertToSmallIntAboveMaxValue() { - Integer invalidValue = Short.MAX_VALUE + 1; - assertThrows(IllegalArgumentException.class, () -> convertToSmallInt(invalidValue)); + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + IllegalArgumentException exception = + assertThrows( + IllegalArgumentException.class, + () -> { + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, null); + CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + }); + assertEquals("Error converting value for cassandraType: date", exception.getMessage()); } @Test - public void testConvertToTinyIntValidInput() { - Integer validValue = 100; - byte result = convertToTinyInt(validValue); - assertEquals(100, result); - } + public void testConvertToCassandraTimestampWithWhitespaceString() { + SpannerColumnType spannerType = new SpannerColumnType("timestamp", false); + SourceColumnType sourceColType = new SourceColumnType("date", null, null); + String columnName = "test_column"; - @Test - public void testConvertToTinyIntBelowMinValue() { - Integer invalidValue = Byte.MIN_VALUE - 1; - assertThrows(IllegalArgumentException.class, () -> convertToTinyInt(invalidValue)); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, " "); - @Test - public void testConvertToTinyIntAboveMaxValue() { - Integer invalidValue = Byte.MAX_VALUE + 1; - assertThrows(IllegalArgumentException.class, () -> convertToTinyInt(invalidValue)); + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + IllegalArgumentException exception = + assertThrows( + IllegalArgumentException.class, + () -> { + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, null); + CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + }); + assertEquals("Error converting value for cassandraType: date", exception.getMessage()); } @Test - public void testEscapeCassandraStringNoQuotes() { - String input = "Hello World"; - String expected = "Hello World"; - String result = escapeCassandraString(input); - assertEquals(expected, result); - } + public void testGetColumnValueByTypeForFloat() { + SpannerColumnType spannerType = new SpannerColumnType("float", false); + SourceColumnType sourceColType = new SourceColumnType("float", null, null); + String columnName = "test_column"; - @Test - public void testEscapeCassandraStringWithSingleQuote() { - String input = "O'Reilly"; - String expected = "O''Reilly"; - String result = escapeCassandraString(input); - assertEquals(expected, result); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, new BigDecimal("5.5")); - @Test - public void testEscapeCassandraStringEmpty() { - String input = ""; - String expected = ""; - String result = escapeCassandraString(input); - assertEquals(expected, result); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); - @Test - public void testEscapeCassandraStringWithMultipleQuotes() { - String input = "It's John's book."; - String expected = "It''s John''s book."; - String result = escapeCassandraString(input); - assertEquals(expected, result); - } + Object result = getColumnValueByType(spannerColDef, sourceColDef, valuesJson, "UTC"); - @Test - public void testConvertToCassandraTimestampWithValidOffset() { - String value = "2024-12-12T10:15:30+02:00"; - String timezoneOffset = "+00:00"; - String expected = "'2024-12-12T08:15:30Z'"; - String result = convertToCassandraTimestamp(value, timezoneOffset); - assertEquals(expected, result); - } + assertTrue(result instanceof PreparedStatementValueObject); - @Test - public void testConvertToCassandraTimestampWithNonZeroOffset() { - String value = "2024-12-12T10:15:30+02:00"; - String timezoneOffset = "+00:00"; - String expected = "'2024-12-12T08:15:30Z'"; - String result = convertToCassandraTimestamp(value, timezoneOffset); - assertEquals(expected, result); + Object actualValue = ((PreparedStatementValueObject) result).value(); + assertEquals(new BigDecimal(5.5), actualValue); } @Test - public void testConvertToCassandraTimestampWithNegativeOffset() { - String value = "2024-12-12T10:15:30-05:00"; - String timezoneOffset = "+00:00"; - String expected = "'2024-12-12T15:15:30Z'"; - String result = convertToCassandraTimestamp(value, timezoneOffset); - assertEquals(expected, result); - } + public void testGetColumnValueByTypeForFloat64() { + SpannerColumnType spannerType = new SpannerColumnType("float64", false); + SourceColumnType sourceColType = new SourceColumnType("double", null, null); + String columnName = "test_column"; - @Test(expected = RuntimeException.class) - public void testConvertToCassandraTimestampWithInvalidFormat() { - String value = "2024-12-12T25:15:30+02:00"; - String timezoneOffset = "+00:00"; - convertToCassandraTimestamp(value, timezoneOffset); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, new BigDecimal("5.5")); - @Test - public void testConvertToCassandraTimestampWithoutTimezone() { - String value = "2024-12-12T10:15:30Z"; - String timezoneOffset = "+00:00"; - String expected = "'2024-12-12T10:15:30Z'"; - String result = convertToCassandraTimestamp(value, timezoneOffset); - assertEquals(expected, result); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); - @Test - public void testConvertToCassandraDateWithValidDate() { - String dateString = "2024-12-12T10:15:30Z"; - LocalDate result = convertToCassandraDate(dateString); - LocalDate expected = LocalDate.of(2024, 12, 12); - assertEquals(expected, result); - } + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, "UTC"); - @Test - public void testConvertToCassandraDateLeapYear() { - String dateString = "2024-02-29T00:00:00Z"; - LocalDate result = convertToCassandraDate(dateString); - LocalDate expected = LocalDate.of(2024, 2, 29); - assertEquals(expected, result); - } + assertTrue(result instanceof PreparedStatementValueObject); - @Test - public void testConvertToCassandraDateWithDifferentTimeZone() { - String dateString = "2024-12-12T10:15:30+02:00"; - LocalDate result = convertToCassandraDate(dateString); - LocalDate expected = LocalDate.of(2024, 12, 12); - assertEquals(expected, result); - } + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); - @Test(expected = IllegalArgumentException.class) - public void testConvertToCassandraDateWithInvalidDate() { - String dateString = "2024-13-12T10:15:30Z"; - convertToCassandraDate(dateString); + assertEquals(5.5, castResult); } @Test - public void testConvertToCassandraTimestampWithValidDate() { - String dateString = "2024-12-12T10:15:30Z"; - Instant result = convertToCassandraTimestamp(dateString); - Instant expected = Instant.parse(dateString); - assertEquals(expected, result); - } + public void testGetColumnValueByTypeForFloat64FromString() { + SpannerColumnType spannerType = new SpannerColumnType("string", false); + SourceColumnType sourceColType = new SourceColumnType("double", null, null); + String columnName = "test_column"; - @Test - public void testConvertToCassandraTimestampWithTimezoneOffset() { - String dateString = "2024-12-12T10:15:30+02:00"; - Instant result = convertToCassandraTimestamp(dateString); - Instant expected = Instant.parse("2024-12-12T08:15:30Z"); - assertEquals(expected, result); - } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, "5.5"); - @Test - public void testConvertToCassandraTimestampLeapYear() { - String dateString = "2024-02-29T00:00:00Z"; - Instant result = convertToCassandraTimestamp(dateString); - Instant expected = Instant.parse(dateString); - assertEquals(expected, result); - } + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); - @Test(expected = IllegalArgumentException.class) - public void testConvertToCassandraTimestampWithInvalidDate() { - String dateString = "2024-13-12T10:15:30Z"; - convertToCassandraTimestamp(dateString); - } + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, "UTC"); - @Test - public void testIsValidUUIDWithValidUUID() { - String validUUID = "123e4567-e89b-12d3-a456-426614174000"; - boolean result = isValidUUID(validUUID); - assertTrue(result); - } + assertTrue(result instanceof PreparedStatementValueObject); - @Test - public void testIsValidUUIDWithInvalidUUID() { - String invalidUUID = "123e4567-e89b-12d3-a456-426614174000Z"; - boolean result = isValidUUID(invalidUUID); - assertFalse(result); - } + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); - @Test - public void testIsValidUUIDWithEmptyString() { - String emptyString = ""; - boolean result = isValidUUID(emptyString); - assertFalse(result); + assertEquals(5.5, castResult); } @Test - public void testIsValidIPAddressWithValidIPv4() { - String validIPv4 = "192.168.1.1"; - boolean result = isValidIPAddress(validIPv4); - assertTrue(result); - } + public void testGetColumnValueByTypeForDecimalFromString() { + SpannerColumnType spannerType = new SpannerColumnType("string", false); + SourceColumnType sourceColType = new SourceColumnType("decimal", null, null); + String columnName = "test_column"; - @Test - public void testIsValidIPAddressWithValidIPv6() { - String validIPv6 = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"; - boolean result = isValidIPAddress(validIPv6); - assertTrue(result); + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, "5.5"); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, "UTC"); + + assertTrue(result instanceof PreparedStatementValueObject); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(BigDecimal.valueOf(5.5), castResult); } @Test - public void testIsValidIPAddressWithInvalidFormat() { - String invalidIP = "999.999.999.999"; - boolean result = isValidIPAddress(invalidIP); - assertFalse(result); + public void testGetColumnValueByTypeForDecimalFromFloat() { + SpannerColumnType spannerType = new SpannerColumnType("float", false); + SourceColumnType sourceColType = new SourceColumnType("decimal", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, 5.5); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, "UTC"); + + assertTrue(result instanceof PreparedStatementValueObject); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(BigDecimal.valueOf(5.5), castResult); } @Test - public void testIsValidJSONWithValidJSON() { - String validJson = "{\"name\":\"John\", \"age\":30}"; - boolean result = isValidJSON(validJson); - assertTrue(result); + public void testGetColumnValueByTypeForDecimalFromFloat64() { + SpannerColumnType spannerType = new SpannerColumnType("float64", false); + SourceColumnType sourceColType = new SourceColumnType("decimal", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, 5.5); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, "UTC"); + + assertTrue(result instanceof PreparedStatementValueObject); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(BigDecimal.valueOf(5.5), castResult); } @Test - public void testIsValidJSONWithInvalidJSON() { - String invalidJson = "{\"name\":\"John\", \"age\":30"; - boolean result = isValidJSON(invalidJson); - assertFalse(result); + public void testGetColumnValueByTypeForFloatFromString() { + SpannerColumnType spannerType = new SpannerColumnType("string", false); + SourceColumnType sourceColType = new SourceColumnType("float", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, "5.5"); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, "UTC"); + + assertTrue(result instanceof PreparedStatementValueObject); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(5.5, castResult); } @Test - public void testIsValidJSONWithEmptyString() { - String emptyString = ""; - boolean result = isValidJSON(emptyString); - assertFalse(result); + public void testGetColumnValueByTypeForBigIntFromString() { + SpannerColumnType spannerType = new SpannerColumnType("string", false); + SourceColumnType sourceColType = new SourceColumnType("bigint", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, "5"); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, "UTC"); + + assertTrue(result instanceof PreparedStatementValueObject); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(Long.valueOf("5"), castResult); } @Test - public void testIsValidJSONWithNull() { - String nullString = null; - boolean result = isValidJSON(nullString); - assertFalse(result); + public void testGetColumnValueByTypeForIntFromString() { + SpannerColumnType spannerType = new SpannerColumnType("string", false); + SourceColumnType sourceColType = new SourceColumnType("int", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, "5"); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, "UTC"); + + assertTrue(result instanceof PreparedStatementValueObject); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(Integer.valueOf("5"), castResult); } @Test - public void testConvertToCassandraDate_validDateString() { - String dateString = "2024-12-16T14:30:00Z"; - LocalDate result = CassandraTypeHandler.convertToCassandraDate(dateString); - assertEquals("The parsed LocalDate should be '2024-12-16'", LocalDate.of(2024, 12, 16), result); + public void testGetColumnValueByTypeForSmallIntFromString() { + SpannerColumnType spannerType = new SpannerColumnType("string", false); + SourceColumnType sourceColType = new SourceColumnType("smallint", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, "5"); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, "UTC"); + + assertTrue(result instanceof PreparedStatementValueObject); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(Integer.valueOf("5").shortValue(), castResult); } @Test - public void testConvertToCassandraDate_leapYear() { - String dateString = "2024-02-29T00:00:00Z"; - LocalDate result = CassandraTypeHandler.convertToCassandraDate(dateString); - assertEquals("The parsed LocalDate should be '2024-02-29'", LocalDate.of(2024, 2, 29), result); + public void testGetColumnValueByTypeForTinyIntFromString() { + SpannerColumnType spannerType = new SpannerColumnType("string", false); + SourceColumnType sourceColType = new SourceColumnType("tinyint", null, null); + String columnName = "test_column"; + + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, "5"); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + PreparedStatementValueObject result = + getColumnValueByType(spannerColDef, sourceColDef, valuesJson, "UTC"); + + assertTrue(result instanceof PreparedStatementValueObject); + + Object castResult = CassandraTypeHandler.castToExpectedType(result.dataType(), result.value()); + + assertEquals(Byte.valueOf("5"), castResult); } @Test - public void testConvertToCassandraDate_validDateWithMilliseconds() { - String dateString = "2024-12-16T14:30:00.123Z"; - LocalDate result = CassandraTypeHandler.convertToCassandraDate(dateString); - assertEquals("The parsed LocalDate should be '2024-12-16'", LocalDate.of(2024, 12, 16), result); + public void testGetColumnValueByTypeForBytes() { + SpannerColumnType spannerType = new SpannerColumnType("bytes", false); + SourceColumnType sourceColType = new SourceColumnType("bytes", null, null); + String columnName = "test_column"; + + byte[] expectedBytes = new byte[] {1, 2, 3, 4, 5}; + StringBuilder binaryString = new StringBuilder(); + for (byte b : expectedBytes) { + binaryString.append(String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0')); + } + JSONObject valuesJson = new JSONObject(); + valuesJson.put(columnName, binaryString.toString()); + + SpannerColumnDefinition spannerColDef = new SpannerColumnDefinition(columnName, spannerType); + SourceColumnDefinition sourceColDef = new SourceColumnDefinition(columnName, sourceColType); + + Object result = getColumnValueByType(spannerColDef, sourceColDef, valuesJson, "UTC"); + + assertTrue(result instanceof PreparedStatementValueObject); + + Object actualValue = ((PreparedStatementValueObject) result).value(); + assertArrayEquals(expectedBytes, (byte[]) actualValue); } @Test - public void testConvertToCassandraDate_timezoneOffsetImpact() { - String dateString = "2024-12-16T14:30:00+01:00"; - LocalDate result = CassandraTypeHandler.convertToCassandraDate(dateString); + public void testCastToExpectedTypeForVariousTypes() throws UnknownHostException { + assertEquals("Test String", castToExpectedType("text", "Test String")); + assertEquals(123L, castToExpectedType("bigint", "123")); + assertEquals(true, castToExpectedType("boolean", "true")); + assertEquals( + new BigDecimal("123.456"), + castToExpectedType("decimal", new BigDecimal("123.456").toString())); + assertEquals(123.456, castToExpectedType("double", "123.456")); + assertEquals(123.45f, ((Double) castToExpectedType("float", "123.45")).floatValue(), 0.00001); + assertEquals(InetAddress.getByName("127.0.0.1"), castToExpectedType("inet", "127.0.0.1")); + assertEquals(123, castToExpectedType("int", "123")); + assertEquals((short) 123, castToExpectedType("smallint", "123")); assertEquals( - "The parsed LocalDate should be '2024-12-16' regardless of timezone.", - LocalDate.of(2024, 12, 16), - result); + UUID.fromString("123e4567-e89b-12d3-a456-426614174000"), + castToExpectedType("uuid", "123e4567-e89b-12d3-a456-426614174000")); + assertEquals((byte) 100, castToExpectedType("tinyint", "100")); + assertEquals( + new BigInteger("123456789123456789123456789"), + castToExpectedType("varint", "123456789123456789123456789")); + String timeString = "14:30:45"; + Object localTime1 = castToExpectedType("time", "14:30:45"); + assertTrue(localTime1 instanceof LocalTime); + assertEquals( + Duration.ofHours(5), castToExpectedType("duration", Duration.ofHours(5).toString())); } @Test - public void testConvertToCassandraDate_validDateWithOffset() { - String dateString = "2024-12-16T14:30:00+01:00"; - LocalDate result = CassandraTypeHandler.convertToCassandraDate(dateString); - assertEquals("The parsed LocalDate should be '2024-12-16'", LocalDate.of(2024, 12, 16), result); + public void testCastToExpectedTypeForJSONArrayStringifyToSet() { + String cassandraType = "set"; + String columnValue = "[1, 2, 3]"; + Object result = castToExpectedType(cassandraType, columnValue); + assertTrue(result instanceof Set); + assertEquals(3, ((Set) result).size()); } @Test - public void testConvertToCassandraDate_withTimeZoneOffset() { - String validDateWithOffset = "2024-12-16T14:30:00+02:00"; - LocalDate result = CassandraTypeHandler.convertToCassandraDate(validDateWithOffset); - assertNotNull(String.valueOf(result), "The result should not be null"); - assertEquals( - "The parsed LocalDate should match the expected value (timezone offset ignored).", - LocalDate.of(2024, 12, 16), - result); + public void testCastToExpectedTypeForJSONObjectStringifyToMap() { + String cassandraType = "map"; + String columnValue = "{\"2024-12-12\": \"One\", \"2\": \"Two\"}"; + assertThrows( + IllegalArgumentException.class, + () -> { + castToExpectedType(cassandraType, columnValue); + }); } @Test - public void testConvertToCassandraDate_endOfMonth() { - String endOfMonthDate = "2024-01-31T12:00:00Z"; - LocalDate result = CassandraTypeHandler.convertToCassandraDate(endOfMonthDate); - assertNotNull(String.valueOf(result), "The result should not be null"); - assertEquals( - "The parsed LocalDate should be correct for end of month.", - LocalDate.of(2024, 1, 31), - result); + public void testCastToExpectedTypeForExceptionScenario() { + String cassandraType = "int"; + String columnValue = "InvalidInt"; + assertThrows( + IllegalArgumentException.class, + () -> { + castToExpectedType(cassandraType, columnValue); + }); } @Test - public void testParseDate_validStringWithCustomFormatter() { - String dateStr = "2024-12-16T14:30:00.000"; - String formatter = "yyyy-MM-dd'T'HH:mm:ss.SSS"; - String colName = "testDate"; - - LocalDate result = CassandraTypeHandler.parseDate(colName, dateStr, formatter); - - assertNotNull(String.valueOf(result), "The parsed LocalDate should not be null."); - assertEquals( - "The parsed LocalDate should match the expected value.", - LocalDate.of(2024, 12, 16), - result); + public void testGetColumnValueByTypeForNullBothColumnDefs() { + JSONObject valuesJson = mock(JSONObject.class); + String sourceDbTimezoneOffset = null; + assertThrows( + IllegalArgumentException.class, + () -> { + getColumnValueByType(null, null, valuesJson, sourceDbTimezoneOffset); + }); } @Test - public void testParseDate_validString() { - String validDateStr = "2024-12-16T14:30:00.000+0000"; - String formatter = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; - String colName = "testDate"; - LocalDate result = CassandraTypeHandler.parseDate(colName, validDateStr, formatter); - assertNotNull(result); - assertEquals(LocalDate.of(2024, 12, 16), result); + public void testCastToExpectedTypeForAscii() { + String expected = "test string"; + Object result = CassandraTypeHandler.castToExpectedType("ascii", expected); + assertEquals(expected, result); } @Test - public void testParseDate_validDate() { - Date date = new Date(1700000000000L); - String colName = "testDate"; - - LocalDate result = CassandraTypeHandler.parseDate(colName, date, "yyyy-MM-dd'T'HH:mm:ss.SSSZ"); + public void testCastToExpectedTypeForVarchar() { + String expected = "test varchar"; + Object result = CassandraTypeHandler.castToExpectedType("varchar", expected); + assertEquals(expected, result); + } - assertNotNull(result); - assertNotEquals(LocalDate.of(2024, 12, 15), result); + @Test + public void testCastToExpectedTypeForList() { + JSONArray listValue = new JSONArray(Arrays.asList("value1", "value2")); + Object result = CassandraTypeHandler.castToExpectedType("list", listValue.toString()); + assertTrue(result instanceof List); + assertEquals(2, ((List) result).size()); } @Test - public void testHandleCassandraGenericDateType_NullFormatter() { - String newValuesString = "{\"date\":\"2024-12-16T10:15:30.000+0000\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "date"; - LocalDate result = - CassandraTypeHandler.handleCassandraGenericDateType(colKey, newValuesJson, null); - assertEquals(LocalDate.of(2024, 12, 16), result); + public void testCastToExpectedTypeForSet() { + JSONArray setValue = new JSONArray(Arrays.asList("value1", "value2")); + Object result = CassandraTypeHandler.castToExpectedType("set", setValue.toString()); + assertTrue(result instanceof Set); + assertEquals(2, ((Set) result).size()); } @Test - public void testHandleStringifiedJsonToList_InvalidFormat() { - String newValuesString = "{\"column\": \"{\\\"key\\\":\\\"value\\\"}\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "column"; - IllegalArgumentException thrown = - assertThrows( - IllegalArgumentException.class, - () -> { - CassandraTypeHandler.handleStringifiedJsonToList(colKey, newValuesJson); - }); - assertTrue(thrown.getMessage().contains("Invalid stringified JSON array format")); + public void testCastToExpectedTypeForInvalidType() { + Object object = CassandraTypeHandler.castToExpectedType("unknownType", new Object()); + assertNotNull(object); } @Test - public void testHandleStringifiedJsonToList_NullInput() { - JSONObject newValuesJson = null; - String colKey = "column"; + public void testCastToExpectedTypeForNull() { assertThrows( NullPointerException.class, () -> { - CassandraTypeHandler.handleStringifiedJsonToList(colKey, newValuesJson); + CassandraTypeHandler.castToExpectedType("text", null); }); } @Test - public void testHandleStringifiedJsonToMap_EmptyString() { - // Test case with an empty string as input, which is also an invalid JSON format - String newValuesString = "{\"column\": \"\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "column"; - IllegalArgumentException thrown = - assertThrows( - IllegalArgumentException.class, - () -> { - CassandraTypeHandler.handleStringifiedJsonToMap(colKey, newValuesJson); - }); - assertTrue(thrown.getMessage().contains("Invalid stringified JSON format for column")); + public void testCastToExpectedTypeForDate_String() { + String dateString = "2025-01-09"; // Format: yyyy-MM-dd + Object result = CassandraTypeHandler.castToExpectedType("date", dateString); + LocalDate expected = LocalDate.parse(dateString); + assertEquals(expected, result); } @Test - public void testHandleStringifiedJsonToMap_NonJsonString() { - String newValuesString = "{\"column\": \"just a plain string\"}"; - JSONObject newValuesJson = new JSONObject(newValuesString); - String colKey = "column"; - IllegalArgumentException thrown = + public void testCastToExpectedTypeForDate_InvalidString() { + String invalidDateString = "invalid-date"; + IllegalArgumentException exception = assertThrows( IllegalArgumentException.class, () -> { - CassandraTypeHandler.handleStringifiedJsonToMap(colKey, newValuesJson); + CassandraTypeHandler.castToExpectedType("date", invalidDateString); }); - assertTrue(thrown.getMessage().contains("Invalid stringified JSON format for column")); - } - - @Test - public void testHandleCassandraVarintType_ValidByteArray() { - JSONObject valuesJson = new JSONObject(); - byte[] byteArray = new BigInteger("12345678901234567890").toByteArray(); - valuesJson.put("varint", byteArray); - BigInteger result = CassandraTypeHandler.handleCassandraVarintType("varint", valuesJson); - BigInteger expected = new BigInteger(byteArray); - assertEquals(expected, result); + assertEquals("Error converting value for cassandraType: date", exception.getMessage()); } @Test - public void testHandleCassandraVarintType_InvalidStringFormat() { - JSONObject valuesJson = new JSONObject(); - valuesJson.put("col1", "invalid-number"); + public void testCastToExpectedTypeForDate_UnsupportedType() { + Integer unsupportedType = 123; IllegalArgumentException exception = assertThrows( IllegalArgumentException.class, () -> { - handleCassandraVarintType("col1", valuesJson); + CassandraTypeHandler.castToExpectedType("date", unsupportedType); }); - assertTrue(exception.getMessage().contains("Invalid varint format (string) for column: col1")); + assertEquals("Error converting value for cassandraType: date", exception.getMessage()); } @Test - public void testParseDate_UnsupportedType() { - JSONObject valuesJson = new JSONObject(); - valuesJson.put("col1", 12345); - String formatter = "yyyy-MM-dd"; + public void testHandleCassandraVarintType_String() { + String validString = "12345678901234567890"; + Object result = CassandraTypeHandler.castToExpectedType("varint", validString); + BigInteger expected = new BigInteger(validString); + assertEquals(expected, result); + } + + @Test + public void testHandleCassandraVarintType_InvalidString() { + String invalidString = "invalid-number"; IllegalArgumentException exception = assertThrows( IllegalArgumentException.class, () -> { - CassandraTypeHandler.parseDate("col1", valuesJson.get("col1"), formatter); + CassandraTypeHandler.castToExpectedType("varint", invalidString); }); - assertTrue(exception.getMessage().contains("Unsupported type for column col1")); + assertEquals("Error converting value for cassandraType: varint", exception.getMessage()); } @Test - public void testHandleCassandraUuidType_ValidUuidString() { - JSONObject valuesJson = new JSONObject(); - String validUuidString = "123e4567-e89b-12d3-a456-426614174000"; - valuesJson.put("col1", validUuidString); - UUID result = handleCassandraUuidType("col1", valuesJson); - UUID expectedUuid = UUID.fromString(validUuidString); - assertEquals(expectedUuid, result); - } - - @Test - public void testHandleCassandraInetAddressType_Hostname() { - JSONObject valuesJson = new JSONObject(); - valuesJson.put("col1", "www.google.com"); + public void testHandleCassandraVarintType_UnsupportedType() { + String unsupportedType = "dsdsdd"; IllegalArgumentException exception = assertThrows( IllegalArgumentException.class, () -> { - CassandraTypeHandler.handleCassandraInetAddressType("col1", valuesJson); + CassandraTypeHandler.castToExpectedType("varint", unsupportedType); }); - assertTrue(exception.getMessage().contains("Invalid IP address format for column: col1")); + assertEquals("Error converting value for cassandraType: varint", exception.getMessage()); } } diff --git a/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/processor/SourceProcessorFactoryTest.java b/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/processor/SourceProcessorFactoryTest.java index eb29cd0d0a..a5e4f583ba 100644 --- a/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/processor/SourceProcessorFactoryTest.java +++ b/v2/spanner-to-sourcedb/src/test/java/com/google/cloud/teleport/v2/templates/dbutils/processor/SourceProcessorFactoryTest.java @@ -25,6 +25,7 @@ import com.google.cloud.teleport.v2.templates.dbutils.connection.JdbcConnectionHelper; import com.google.cloud.teleport.v2.templates.dbutils.dao.source.CassandraDao; import com.google.cloud.teleport.v2.templates.dbutils.dao.source.JdbcDao; +import com.google.cloud.teleport.v2.templates.dbutils.dml.CassandraDMLGenerator; import com.google.cloud.teleport.v2.templates.dbutils.dml.MySQLDMLGenerator; import com.google.cloud.teleport.v2.templates.exceptions.UnsupportedSourceException; import java.util.Arrays; @@ -104,8 +105,7 @@ public void testCreateSourceProcessor_cassandra_validSource() throws Exception { Constants.SOURCE_CASSANDRA, shards, maxConnections); Assert.assertNotNull(processor); - // ToDo this Particular line will get enable in DML PR - // Assert.assertTrue(processor.getDmlGenerator() instanceof CassandraDMLGenerator); + Assert.assertTrue(processor.getDmlGenerator() instanceof CassandraDMLGenerator); Assert.assertEquals(1, processor.getSourceDaoMap().size()); Assert.assertTrue(processor.getSourceDaoMap().get("shard1") instanceof CassandraDao); } diff --git a/v2/spanner-to-sourcedb/src/test/resources/cassandraSession.json b/v2/spanner-to-sourcedb/src/test/resources/cassandraSession.json new file mode 100644 index 0000000000..3bb4bd8942 --- /dev/null +++ b/v2/spanner-to-sourcedb/src/test/resources/cassandraSession.json @@ -0,0 +1,1064 @@ +{ + "SyntheticPKeys": { + "t4": { + "ColId": "c22", + "Sequence": 0 + } + }, + "SpSchema": { + "sample_table": { + "Name": "sample_table", + "ColIds": [ + "id", + "varchar_column", + "tinyint_column", + "text_column", + "date_column", + "smallint_column", + "mediumint_column", + "bigint_column", + "float_column", + "double_column", + "decimal_column", + "datetime_column", + "timestamp_column", + "time_column", + "year_column", + "char_column", + "tinyblob_column", + "tinytext_column", + "blob_column", + "mediumblob_column", + "mediumtext_column", + "longblob_column", + "longtext_column", + "enum_column", + "set_column", + "bool_column", + "binary_column", + "varbinary_column" + ], + "ColDefs": { + "bigint_column": { + "Name": "bigint_column", + "T": { + "Name": "INT64" + }, + "Id": "c9" + }, + "binary_column": { + "Name": "binary_column", + "T": { + "Name": "BYTES" + }, + "Id": "c25" + }, + "blob_column": { + "Name": "blob_column", + "T": { + "Name": "blob", + "Len": 9223372036854776000, + "IsArray": false + }, + "Id": "c11", + "NotNull": false, + "Comment": "From: blob_column blob(65535)" + }, + "bool_column": { + "Name": "bool_column", + "T": { + "Name": "BOOL" + }, + "Id": "c19" + }, + "char_column": { + "Name": "char_column", + "T": { + "Name": "STRING" + }, + "Id": "c10" + }, + "date_column": { + "Name": "date_column", + "T": { + "Name": "DATE" + }, + "Id": "c13" + }, + "datetime_column": { + "Name": "datetime_column", + "T": { + "Name": "TIMESTAMP" + }, + "Id": "c15" + }, + "decimal_column": { + "Name": "decimal_column", + "T": { + "Name": "NUMERIC" + }, + "Id": "c28" + }, + "double_column": { + "Name": "double_column", + "T": { + "Name": "FLOAT64" + }, + "Id": "c17" + }, + "enum_column": { + "Name": "enum_column", + "T": { + "Name": "STRING" + }, + "Id": "c24" + }, + "float_column": { + "Name": "float_column", + "T": { + "Name": "FLOAT64" + }, + "Id": "c14" + }, + "id": { + "Name": "id", + "T": { + "Name": "bigint", + "Len": 0, + "IsArray": false + }, + "Id": "c2", + "NotNull": true, + "Comment": "From: id int" + }, + "longblob_column": { + "Name": "longblob_column", + "T": { + "Name": "BYTES" + }, + "Id": "c23" + }, + "longtext_column": { + "Name": "longtext_column", + "T": { + "Name": "STRING" + }, + "Id": "c12" + }, + "mediumblob_column": { + "Name": "mediumblob_column", + "T": { + "Name": "BYTES" + }, + "Id": "c18" + }, + "mediumint_column": { + "Name": "mediumint_column", + "T": { + "Name": "INT64" + }, + "Id": "c8" + }, + "mediumtext_column": { + "Name": "mediumtext_column", + "T": { + "Name": "STRING" + }, + "Id": "c22" + }, + "set_column": { + "Name": "set_column", + "T": { + "Name": "STRING" + }, + "Id": "c5" + }, + "smallint_column": { + "Name": "smallint_column", + "T": { + "Name": "INT64" + }, + "Id": "c3" + }, + "text_column": { + "Name": "text_column", + "T": { + "Name": "STRING" + }, + "Id": "c27" + }, + "time_column": { + "Name": "time_column", + "T": { + "Name": "STRING" + }, + "Id": "c29" + }, + "timestamp_column": { + "Name": "timestamp_column", + "T": { + "Name": "TIMESTAMP" + }, + "Id": "c16" + }, + "tinyblob_column": { + "Name": "tinyblob_column", + "T": { + "Name": "BYTES" + }, + "NotNull": false, + "Id": "c4" + }, + "tinyint_column": { + "Name": "tinyint_column", + "T": { + "Name": "INT64" + }, + "Id": "c26" + }, + "tinytext_column": { + "Name": "tinytext_column", + "T": { + "Name": "STRING" + }, + "Id": "c7" + }, + "varbinary_column": { + "Name": "varbinary_column", + "T": { + "Name": "BYTES" + }, + "Id": "c20" + }, + "varchar_column": { + "Name": "varchar_column", + "T": { + "Name": "varchar", + "Len": 20, + "IsArray": false + }, + "Id": "c21", + "NotNull": false, + "Comment": "From: varchar_column varchar(20)" + }, + "year_column": { + "Name": "year_column", + "T": { + "Name": "STRING" + }, + "Id": "c6" + } + }, + "PrimaryKeys": [ + { + "ColId": "id", + "Desc": false, + "Order": 1 + }, + { + "ColId": "id", + "Desc": false, + "Order": 1 + } + ], + "Id": "t1", + "Comment": "Spanner schema for source table sample_table" + }, + "Singers": { + "Name": "Singers", + "ColIds": [ + "c5", + "c6", + "c7", + "c8" + ], + "ColDefs": { + "c5": { + "Name": "SingerId", + "T": { + "Name": "INT64", + "Len": 0, + "IsArray": false + }, + "NotNull": true, + "Comment": "From: SingerId int", + "Id": "c5" + }, + "c6": { + "Name": "Bday", + "T": { + "Name": "TIMESTAMP", + "Len": 1024, + "IsArray": false + }, + "NotNull": false, + "Comment": "From: FirstName varchar(1024)", + "Id": "c6" + }, + "c7": { + "Name": "LastName", + "T": { + "Name": "STRING", + "Len": 1024, + "IsArray": false + }, + "NotNull": false, + "Comment": "From: LastName varchar(1024)", + "Id": "c7" + }, + "c8": { + "Name": "hb_shardId", + "T": { + "Name": "STRING", + "Len": 1024, + "IsArray": false + }, + "NotNull": false, + "Comment": "HB shard id", + "Id": "c8" + } + }, + "PrimaryKeys": [ + { + "ColId": "c5", + "Desc": false, + "Order": 1 + } + ], + "Id": "t1" + }, + "contact": { + "Name": "contact", + "ColIds": [ + "c18", + "c19", + "c20", + "c21" + ], + "ColDefs": { + "c18": { + "Name": "ID", + "T": { + "Name": "INT64", + "Len": 0, + "IsArray": false + }, + "NotNull": true, + "Comment": "From: ID int", + "Id": "c18" + }, + "c19": { + "Name": "Customer_Id", + "T": { + "Name": "INT64", + "Len": 0, + "IsArray": false + }, + "NotNull": true, + "Comment": "From: Customer_Id int", + "Id": "c19" + }, + "c20": { + "Name": "Customer_Info", + "T": { + "Name": "STRING", + "Len": 50, + "IsArray": false + }, + "NotNull": true, + "Comment": "From: Customer_Info varchar(50)", + "Id": "c20" + }, + "c21": { + "Name": "Type", + "T": { + "Name": "STRING", + "Len": 50, + "IsArray": false + }, + "NotNull": true, + "Comment": "From: Type varchar(50)", + "Id": "c21" + } + }, + "PrimaryKeys": [ + { + "ColId": "c18", + "Desc": false, + "Order": 1 + }, + { + "ColId": "c19", + "Desc": false, + "Order": 2 + } + ], + "Id": "t2" + }, + "customer": { + "Name": "customer", + "ColIds": [ + "c10", + "c11", + "c12" + ], + "ColDefs": { + "c10": { + "Name": "ID", + "T": { + "Name": "INT64", + "Len": 0, + "IsArray": false + }, + "NotNull": true, + "Comment": "From: ID int", + "Id": "c10" + }, + "c11": { + "Name": "Name", + "T": { + "Name": "STRING", + "Len": 50, + "IsArray": false + }, + "NotNull": true, + "Comment": "From: Name varchar(50)", + "Id": "c11" + }, + "c12": { + "Name": "City", + "T": { + "Name": "STRING", + "Len": 50, + "IsArray": false + }, + "NotNull": true, + "Comment": "From: City varchar(50)", + "Id": "c12" + } + }, + "PrimaryKeys": [ + { + "ColId": "c10", + "Desc": false, + "Order": 1 + }, + { + "ColId": "c11", + "Desc": false, + "Order": 2 + } + ], + "Id": "t3" + }, + "Persons": { + "Name": "Persons", + "ColIds": [ + "c13", + "c14", + "c15", + "c16", + "c17", + "c22" + ], + "ColDefs": { + "c13": { + "Name": "PersonID", + "T": { + "Name": "INT64", + "Len": 0, + "IsArray": false + }, + "NotNull": false, + "Comment": "From: PersonID int", + "Id": "c13" + }, + "c14": { + "Name": "LastName", + "T": { + "Name": "STRING", + "Len": 255, + "IsArray": false + }, + "NotNull": false, + "Comment": "From: LastName varchar(255)", + "Id": "c14" + }, + "c15": { + "Name": "FirstName", + "T": { + "Name": "STRING", + "Len": 255, + "IsArray": false + }, + "NotNull": false, + "Comment": "From: FirstName varchar(255)", + "Id": "c15" + }, + "c16": { + "Name": "Address", + "T": { + "Name": "STRING", + "Len": 255, + "IsArray": false + }, + "NotNull": false, + "Comment": "From: Address varchar(255)", + "Id": "c16" + }, + "c17": { + "Name": "City", + "T": { + "Name": "STRING", + "Len": 255, + "IsArray": false + }, + "NotNull": false, + "Comment": "From: City varchar(255)", + "Id": "c17" + }, + "c22": { + "Name": "synth_id", + "T": { + "Name": "STRING", + "Len": 50, + "IsArray": false + }, + "NotNull": false, + "Comment": "", + "Id": "c22" + } + }, + "PrimaryKeys": [ + { + "ColId": "c22", + "Desc": false, + "Order": 1 + } + ], + "Id": "t4" + } + }, + "SrcSchema": { + "sample_table": { + "Name": "sample_table", + "Schema": "test", + "ColIds": [ + "id", + "varchar_column", + "tinyint_column", + "text_column", + "date_column", + "smallint_column", + "mediumint_column", + "bigint_column", + "float_column", + "double_column", + "decimal_column", + "datetime_column", + "timestamp_column", + "time_column", + "year_column", + "char_column", + "tinyblob_column", + "tinytext_column", + "blob_column", + "mediumblob_column", + "mediumtext_column", + "longblob_column", + "longtext_column", + "enum_column", + "set_column", + "bool_column", + "binary_column", + "varbinary_column", + "blob_column" + ], + "ColDefs": { + "bigint_column": { + "Name": "bigint_column", + "Type": { + "Name": "bigint" + }, + "Id": "c9" + }, + "binary_column": { + "Name": "binary_column", + "Type": { + "Name": "binary" + }, + "Id": "c25" + }, + "blob_column": { + "Name": "blob_column", + "Type": { + "Name": "blob", + "Mods": [ + 65535 + ], + "ArrayBounds": null + }, + "Id": "c11", + "NotNull": false, + "Ignored": { + "Check": false, + "Identity": false, + "Default": true, + "Exclusion": false, + "ForeignKey": false, + "AutoIncrement": false + } + }, + "bool_column": { + "Name": "bool_column", + "Type": { + "Name": "tinyint" + }, + "Id": "c19" + }, + "char_column": { + "Name": "char_column", + "Type": { + "Name": "varchar" + }, + "Id": "c10" + }, + "date_column": { + "Name": "date_column", + "Type": { + "Name": "timestamp" + }, + "Id": "c13" + }, + "datetime_column": { + "Name": "datetime_column", + "Type": { + "Name": "timestamp" + }, + "Id": "c15" + }, + "decimal_column": { + "Name": "decimal_column", + "Type": { + "Name": "float" + }, + "Id": "c28" + }, + "double_column": { + "Name": "double_column", + "Type": { + "Name": "float" + }, + "Id": "c17" + }, + "enum_column": { + "Name": "enum_column", + "Type": { + "Name": "enum" + }, + "Id": "c24" + }, + "float_column": { + "Name": "float_column", + "Type": { + "Name": "float" + }, + "Id": "c14" + }, + "id": { + "Name": "id", + "Type": { + "Name": "integer", + "Mods": null, + "ArrayBounds": null + }, + "Id": "c2", + "NotNull": true, + "Ignored": { + "Check": false, + "Identity": false, + "Default": false, + "Exclusion": false, + "ForeignKey": false, + "AutoIncrement": false + } + }, + "longblob_column": { + "Name": "longblob_column", + "Type": { + "Name": "blob" + }, + "Id": "c23" + }, + "longtext_column": { + "Name": "longtext_column", + "Type": { + "Name": "varchar" + }, + "Id": "c12" + }, + "mediumblob_column": { + "Name": "mediumblob_column", + "Type": { + "Name": "blob" + }, + "Id": "c18" + }, + "mediumint_column": { + "Name": "mediumint_column", + "Type": { + "Name": "int" + }, + "Id": "c8" + }, + "mediumtext_column": { + "Name": "mediumtext_column", + "Type": { + "Name": "varchar" + }, + "Id": "c22" + }, + "set_column": { + "Name": "set_column", + "Type": { + "Name": "set" + }, + "Id": "c5" + }, + "smallint_column": { + "Name": "smallint_column", + "Type": { + "Name": "int" + }, + "Id": "c3" + }, + "text_column": { + "Name": "text_column", + "Type": { + "Name": "varchar" + }, + "Id": "c27" + }, + "time_column": { + "Name": "time_column", + "Type": { + "Name": "time" + }, + "Id": "c29" + }, + "timestamp_column": { + "Name": "timestamp_column", + "Type": { + "Name": "timestamp" + }, + "Id": "c16" + }, + "tinyblob_column": { + "Name": "tinyblob_column", + "Type": { + "Name": "blob" + }, + "Id": "c4" + }, + "tinyint_column": { + "Name": "tinyint_column", + "Type": { + "Name": "tinyint" + }, + "Id": "c26" + }, + "tinytext_column": { + "Name": "tinytext_column", + "Type": { + "Name": "varchar" + }, + "Id": "c7" + }, + "varbinary_column": { + "Name": "varbinary_column", + "Type": { + "Name": "varbinary" + }, + "Id": "c20" + }, + "varchar_column": { + "Name": "varchar_column", + "Type": { + "Name": "String", + "Mods": [ + 20 + ], + "ArrayBounds": null + }, + "Id": "c21", + "NotNull": false, + "Ignored": { + "Check": false, + "Identity": false, + "Default": true, + "Exclusion": false, + "ForeignKey": false, + "AutoIncrement": false + } + }, + "year_column": { + "Name": "year_column", + "Type": { + "Name": "year" + }, + "Id": "c6" + } + }, + "PrimaryKeys": [ + { + "ColId": "id", + "Desc": false, + "Order": 1 + } + ], + "Id": "t1" + }, + "Singers": { + "Name": "Singers", + "Schema": "ui_demo", + "ColIds": [ + "c5", + "c6", + "c7", + "c8" + ], + "ColDefs": { + "c5": { + "Name": "SingerId", + "Type": { + "Name": "int" + }, + "Id": "c5" + }, + "c6": { + "Name": "Bday", + "Type": { + "Name": "timestamp" + }, + "Id": "c6" + }, + "c7": { + "Name": "LastName", + "Type": { + "Name": "String" + }, + "Id": "c7" + }, + "c8": { + "Name": "Age", + "Type": { + "Name": "varchar" + }, + "Id": "c8" + } + }, + "PrimaryKeys": [ + { + "ColId": "c5", + "Desc": false, + "Order": 1 + } + ], + "Id": "t1" + }, + "contact": { + "Name": "contact", + "Schema": "ui_demo", + "ColIds": [ + "c18", + "c19", + "c20", + "c21" + ], + "ColDefs": { + "c18": { + "Name": "ID", + "Type": { + "Name": "int" + }, + "Id": "c18" + }, + "c19": { + "Name": "Customer_Id", + "Type": { + "Name": "int" + }, + "Id": "c19" + }, + "c20": { + "Name": "Customer_Info", + "Type": { + "Name": "varchar" + }, + "Id": "c20" + }, + "c21": { + "Name": "Type", + "Type": { + "Name": "varchar" + }, + "Id": "c21" + } + }, + "PrimaryKeys": [ + { + "ColId": "c18", + "Desc": false, + "Order": 1 + }, + { + "ColId": "c19", + "Desc": false, + "Order": 2 + } + ], + "ForeignKeys": null, + "Indexes": null, + "Id": "t2" + }, + "customer": { + "Name": "customer", + "Schema": "ui_demo", + "ColIds": [ + "c10", + "c11", + "c12" + ], + "ColDefs": { + "c10": { + "Name": "ID", + "Type": { + "Name": "int" + }, + "Id": "c10" + }, + "c11": { + "Name": "Name", + "Type": { + "Name": "varchar" + }, + "Id": "c11" + }, + "c12": { + "Name": "City", + "Type": { + "Name": "varchar" + }, + "Id": "c12" + } + }, + "PrimaryKeys": [ + { + "ColId": "c10", + "Desc": false, + "Order": 1 + } + ], + "ForeignKeys": null, + "Indexes": null, + "Id": "t3" + }, + "Persons": { + "Name": "Persons", + "Schema": "ui_demo", + "ColIds": [ + "c13", + "c14", + "c15", + "c16", + "c17" + ], + "ColDefs": { + "c13": { + "Name": "PersonID", + "Type": { + "Name": "int" + }, + "Id": "c13" + }, + "c14": { + "Name": "LastName", + "Type": { + "Name": "varchar" + }, + "Id": "c14" + }, + "c15": { + "Name": "FirstName", + "Type": { + "Name": "varchar" + }, + "Id": "c15" + }, + "c16": { + "Name": "Address", + "Type": { + "Name": "varchar" + }, + "Id": "c16" + }, + "c17": { + "Name": "City", + "Type": { + "Name": "varchar" + }, + "Id": "c17" + } + }, + "PrimaryKeys": null, + "ForeignKeys": null, + "Indexes": null, + "Id": "t4" + } + }, + "ToSource": { + "sample_table": { + "Name": "sample_table", + "Cols": { + "bigint_column": "bigint_column", + "binary_column": "binary_column", + "blob_column": "blob_column", + "bool_column": "bool_column", + "char_column": "char_column", + "date_column": "date_column", + "datetime_column": "datetime_column", + "decimal_column": "decimal_column", + "double_column": "double_column", + "enum_column": "enum_column", + "float_column": "float_column", + "id": "id", + "longblob_column": "longblob_column", + "longtext_column": "longtext_column", + "mediumblob_column": "mediumblob_column", + "mediumint_column": "mediumint_column", + "mediumtext_column": "mediumtext_column", + "set_column": "set_column", + "smallint_column": "smallint_column", + "text_column": "text_column", + "time_column": "time_column", + "timestamp_column": "timestamp_column", + "tinyblob_column": "tinyblob_column", + "tinyint_column": "tinyint_column", + "tinytext_column": "tinytext_column", + "varbinary_column": "varbinary_column", + "varchar_column": "varchar_column", + "year_column": "year_column" + } + } + }, + "ToSpanner": { + "sample_table": { + "Name": "sample_table", + "Cols": { + "blob_column": "blob_column", + "id": "id", + "varchar_column": "varchar_column" + } + } + } +} \ No newline at end of file